3

I am creating the APIs in AWS API Gateway. All the infrastructure in AWS is managed by using terraform In order to continue the same would like add the API config in terraform. I have the API resource definition in swagger generated by swagger dependency tool added in the application.

I need to integrate it with terraform, but when I try to apply I have to import each resource from the AWS created by swagger multiple times. Only the API Gateway configuration should be in terraform and the resource definition should be from the swagger, Is there any way to achieve that. Also I need to automate the flow for 100s of APIs, please suggest how it can be done.

Please share any relevant github links

Here is what I have tried so far,

resource "aws_api_gateway_rest_api" "api" { name = "Hello-API" description = "Proxy to handle requests to our API" body = "${file("api_swagger_example.json")}" } //Resource created by swagger data "aws_api_gateway_resource" "helloApp" { rest_api_id = "${aws_api_gateway_rest_api.api.id}" path = "/api/v1/hello" } //Need to import from first, since it was created using swagger resource "aws_api_gateway_method" "helloApp-POST" { rest_api_id = "${aws_api_gateway_rest_api.api.id}" resource_id = "${data.aws_api_gateway_resource.helloApp.id}" http_method = "POST" authorization = "NONE" } //Importing first resource "aws_api_gateway_method_response" "response_200" { rest_api_id = "${aws_api_gateway_rest_api.api.id}" resource_id = "${data.aws_api_gateway_resource.helloApp.id}" http_method = "${aws_api_gateway_method.helloApp-POST.http_method}" status_code = "200" response_parameters = "${var.method_response_parameters}" } //Importing first resource "aws_api_gateway_method_response" "response_401" { rest_api_id = "${aws_api_gateway_rest_api.api.id}" resource_id = "${data.aws_api_gateway_resource.helloApp.id}" http_method = "${aws_api_gateway_method.helloApp-POST.http_method}" status_code = "401" response_parameters = "${var.method_response_parameters}" } resource "aws_api_gateway_integration_response" "helloApp-ok" { rest_api_id = "${aws_api_gateway_rest_api.api.id}" resource_id = "${data.aws_api_gateway_resource.helloApp.id}" http_method = "${aws_api_gateway_method.helloApp-POST.http_method}" status_code = "${aws_api_gateway_method_response.response_200.status_code}" response_parameters = "${var.integration_response_parameters}" } resource "aws_api_gateway_integration_response" "helloApp-401" { rest_api_id = "${aws_api_gateway_rest_api.api.id}" resource_id = "${data.aws_api_gateway_resource.helloApp.id}" http_method = "${aws_api_gateway_method.helloApp-POST.http_method}" status_code = "${aws_api_gateway_method_response.response_401.status_code}" selection_pattern = "4\\d{2}" response_parameters = "${var.integration_response_parameters}" } //Importing first resource "aws_api_gateway_method_response" "helloApp_response_200" { rest_api_id = "${aws_api_gateway_rest_api.api.id}" resource_id = "${data.aws_api_gateway_resource.helloApp.id}" http_method = "${aws_api_gateway_method.helloApp-POST.http_method}" status_code = "200" response_parameters = "${var.method_response_parameters}" } //Importing first resource "aws_api_gateway_method_response" "helloApp_response_401" { rest_api_id = "${aws_api_gateway_rest_api.api.id}" resource_id = "${data.aws_api_gateway_resource.helloApp.id}" http_method = "${aws_api_gateway_method.helloApp-POST.http_method}" status_code = "401" response_parameters = "${var.method_response_parameters}" } resource "aws_api_gateway_integration" "helloAppIntegration" { rest_api_id = "${aws_api_gateway_rest_api.api.id}" resource_id = "${data.aws_api_gateway_resource.helloApp.id}" http_method = "${aws_api_gateway_method.helloApp-POST.http_method}" type = "HTTP" integration_http_method = "POST" connection_type = "VPC_LINK" connection_id = "${data.aws_api_gateway_vpc_link.hello_vpc_link.id}" uri = "${var.hello-endpoint-url}" request_templates = { "application/json" = <<REQUEST_TEMPLATE $input.json('$') REQUEST_TEMPLATE } } resource "aws_api_gateway_integration_response" "helloApp-ok" { rest_api_id = "${aws_api_gateway_rest_api.api.id}" resource_id = "${data.aws_api_gateway_resource.helloApp.id}" http_method = "${aws_api_gateway_method.helloApp-POST.http_method}" status_code = "${aws_api_gateway_method_response.helloApp_response_200.status_code}" response_parameters = "${var.integration_response_parameters}" } resource "aws_api_gateway_integration_response" "helloApp-401" { rest_api_id = "${aws_api_gateway_rest_api.api.id}" resource_id = "${data.aws_api_gateway_resource.helloApp.id}" http_method = "${aws_api_gateway_method.helloApp-POST.http_method}" status_code = "${aws_api_gateway_method_response.helloApp_response_401.status_code}" selection_pattern = "4\\d{2}" response_parameters = "${var.integration_response_parameters}" } resource "aws_api_gateway_deployment" "deploy-dev" { depends_on = [ "aws_api_gateway_integration.helloAppIntegration", "aws_api_gateway_method.helloApp-POST" ] rest_api_id = "${aws_api_gateway_rest_api.api.id}" stage_name = "dev" } resource "aws_api_gateway_stage" "dev" { stage_name = "dev" rest_api_id = "${aws_api_gateway_rest_api.api.id}" deployment_id = "${aws_api_gateway_deployment.deploy-dev.id}" } resource "aws_api_gateway_usage_plan" "dev-usage-plan" { name = "hello-usage-plan" description = "hello API Basic Usage Plan" api_stages { api_id = "${aws_api_gateway_rest_api.api.id}" stage = "${aws_api_gateway_deployment.deploy-dev.stage_name}" } throttle_settings { burst_limit = 5 rate_limit = 10 } } resource "aws_api_gateway_method_settings" "helloApp-POST" { rest_api_id = "${aws_api_gateway_rest_api.api.id}" stage_name = "${aws_api_gateway_stage.dev.stage_name}" method_path = "${data.aws_api_gateway_resource.helloApp.path_part}/${aws_api_gateway_method.helloApp-POST.http_method}" settings { metrics_enabled = true logging_level = "INFO" } } 

It was so annoying and practically not possible to import every resource for all the APIs and updating. Any better way to integrate?

2
  • What have you tried so far? Have you looked at the body argument in the aws_api_gateway_rest_api resource? Commented Oct 9, 2019 at 6:56
  • Yes, I have used the "body" to integrate swagger with terraform. Adding my implementation in the question Commented Oct 9, 2019 at 22:57

1 Answer 1

6

You need to use a template_file resource which will create a swagger file template for AWS API gateway by reading a source swagger file.

Then just use aws_api_gateway_rest_api resource by passing rendered swagger file as body. To create Integration, you need to add it in swagger file itself.

 data "template_file" "aws_api_swagger" { template = "${file(var.swagger-file-path)}" #Pass the varible value if needed in swagger file vars = { connectionType = "${var.connectiontype}" type = "${var.type}" backend_uri = "https://api.endpoint.url" } } resource "aws_api_gateway_rest_api" "api-gateway" { name = "${var.name}" description = "${var.description}" body = "${data.template_file.aws_api_swagger.rendered}" } 

Swagger file snippet to refer

paths: /: get: tags: - sample description: sample responses: "200": description: Success x-amazon-apigateway-integration: uri: ${backend_url}/health-check connectionType: ${connectionType} passthroughBehavior: "when_no_match" httpMethod: "GET" type: ${type} 

Also refer here to use x-amazon-apigateway-integration in swagger file in details

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.