如何使用Terraform和AWS API Gateway创建API代理

22

我正在尝试使用Terraform在AWS的API Gateway中搭建一个简单的API代理。基本上,我想把根路径进行封装,并将请求代理回另一个端点。这可能是最简单的设置,但我似乎无法在Terraform中使其正常工作。

以下是脚本代码。目前,我能够创建REST API、定义资源和创建方法,但似乎没有办法定义端点。

provider "aws" {
    region = "us-east-1"
}
resource "aws_api_gateway_rest_api" "TerraTest" {
  name = "TerraTest"
  description = "This is my API for demonstration purposes"
}

resource "aws_api_gateway_resource" "TerraProxyResource" {
  rest_api_id = "${aws_api_gateway_rest_api.TerraTest.id}"
  parent_id = "${aws_api_gateway_rest_api.TerraTest.root_resource_id}"
  path_part = "{proxy+}"
}

resource "aws_api_gateway_integration" "integration" {
    rest_api_id = "${aws_api_gateway_rest_api.TerraTest.id}"
    resource_id = "${aws_api_gateway_resource.TerraProxyResource.id}"
    http_method = "${aws_api_gateway_method.mymethod.http_method}"

    type = "HTTP_PROXY"
    uri = "http://api.endpoint.com/{proxy+}"
}

我在这里将类型设置为代理,但我认为URI不是设置端点的正确属性。

resource "aws_api_gateway_method" "mymethod" {
  rest_api_id = "${aws_api_gateway_rest_api.TerraTest.id}"
  resource_id = "${aws_api_gateway_resource.TerraProxyResource.id}"
  http_method = "ANY"
  authorization = "NONE"
}

我希望能在这里创建到另一个端点的映射,但似乎没有相应的属性。(https://github.com/hashicorp/terraform/blob/master/builtin/providers/aws/resource_aws_api_gateway_method.go

resource "aws_api_gateway_api_key" "TerraTestKey" {
  name = "Terra_Test_Key"

  stage_key {
    rest_api_id = "${aws_api_gateway_rest_api.TerraTest.id}"
    stage_name = "${aws_api_gateway_deployment.TerraTestDeployment.stage_name}"
  }
}


resource "aws_api_gateway_deployment" "TerraTestDeployment" {
  rest_api_id = "${aws_api_gateway_rest_api.TerraTest.id}"
  stage_name = "dev"
}

我扫描了源代码,但没有看到我可以设置的任何属性。

有人可以分享一些建议/片段吗?

Tim

Ps. 如果你想尝试自己运行脚本,我把它放在这里:http://textuploader.com/d14sx


1
我在这里找到了我的问题的答案:https://dev59.com/YlkT5IYBdhLWcg3wG8D4 - knaak
你能用详细的代码回答自己的问题吗?我需要参考一下。 - BMW
1
@BMW,我已经在下面添加了它。祝你好运。 - knaak
1个回答

28

这是相关的模块,展示了一个可行的解决方案。它不能独立运行,因为它依赖于其他地方定义的一些变量,但对于任何努力获得AWS代理设置并展示Lambda授权程序集成的人来说,它应该足够有帮助。

provider "aws" {
  region  = "${var.region}"
  profile = "${var.profile}"
}

data "aws_iam_role" "api_user" {
  role_name = "api_user"
}

module "authorizer_lambda" {
  source   = "../lambda"
  name     = "${var.api_name}-authorizer_lambda"
  filename = "authorizer_lambda"
  runtime  = "nodejs4.3"
  role     = "${data.aws_iam_role.api_user.arn}"
}

resource "aws_api_gateway_authorizer" "custom_authorizer" {
  name                   = "${var.api_name}-custom_authorizer"
  rest_api_id            = "${aws_api_gateway_rest_api.ApiGateway.id}"
  authorizer_uri         = "${module.authorizer_lambda.uri}"
  authorizer_credentials = "${data.aws_iam_role.api_user.arn}"
  authorizer_result_ttl_in_seconds = 1
}

resource "aws_api_gateway_rest_api" "ApiGateway" {
  name        = "${var.api_name}"
  description = "${var.api_description}"
}

resource "aws_api_gateway_resource" "ApiProxyResource" {
  rest_api_id = "${aws_api_gateway_rest_api.ApiGateway.id}"
  parent_id   = "${aws_api_gateway_rest_api.ApiGateway.root_resource_id}"
  path_part   = "{proxy+}"
}

resource "aws_api_gateway_integration" "ApiProxyIntegration" {
  rest_api_id              = "${aws_api_gateway_rest_api.ApiGateway.id}"
  resource_id              = "${aws_api_gateway_resource.ApiProxyResource.id}"
    http_method              = "${aws_api_gateway_method.ApiProxyMethod.http_method}"
    type                     = "HTTP_PROXY"
    integration_http_method  = "ANY"
    uri                      = "${format("%s/{proxy}", "${var.base_url}")}"
    passthrough_behavior     = "WHEN_NO_MATCH"
    request_parameters       = "${var.aws_api_gateway_integration_request_parameters}"
}

resource "aws_api_gateway_method" "ApiProxyMethod" {
  rest_api_id                   = "${aws_api_gateway_rest_api.ApiGateway.id}"
  resource_id                   = "${aws_api_gateway_resource.ApiProxyResource.id}"
  http_method                   = "ANY"
  authorization                 = "CUSTOM"
  authorizer_id                 = "${aws_api_gateway_authorizer.custom_authorizer.id}"  
  request_parameters            = {"method.request.path.proxy" = true}
}

resource "aws_api_gateway_deployment" "ApiDeployment" {
  depends_on = ["aws_api_gateway_method.ApiProxyMethod"]
  rest_api_id = "${aws_api_gateway_rest_api.ApiGateway.id}"
  stage_name = "${var.stage_name}"
}

1
${format(...)} 是 Terraform 函数:https://www.terraform.io/docs/configuration/functions/format.html - Christopher Thomas
4
提醒大家,容易被忽视的一个关键点是 aws_api_gateway_method 上的 request_parameters 属性。如果没有它,集成 URI 中的 proxy 参数将无法被识别。 - rayepps
3
继@rayepps的评论之后,看到用于填充ApiProxyIntegration.request_parameters的变量将非常有帮助。 - pdoherty926
由于某些原因,当真实客户端(如Postman)访问时,此操作会返回500个内部服务器错误。 - Facundo La Rocca

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接