Terraform不部署api网关阶段

时间:2016-08-12 06:00:04

标签: aws-api-gateway terraform

我一直在尝试使用terraform创建API网关端点。除了部署舞台的最后部分外,一切似乎都在起作用。

运行terraform apply后,我进入控制台,发现部署尚未发生。我需要手动点击Deploy Api才能使其正常工作。

这是api网关的terraform文件。

variable "region" {}
variable "account_id" {}

resource "aws_api_gateway_rest_api" "online_tax_test_client_report_endpoint_api" {
  name = "online_tax_test_client_report_endpoint_api"
  description = "The endpoint that test has to hit when new client reports are available."
  depends_on = ["aws_lambda_function.onlinetax_test_endpoint_lambda"]
}

resource "aws_api_gateway_resource" "test_client_report_resource" {
  rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}"
  parent_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.root_resource_id}"
  path_part = "test_client_report"
}

resource "aws_api_gateway_method" "test_client_report_method" {
  rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}"
  resource_id = "${aws_api_gateway_resource.test_client_report_resource.id}"
  http_method = "POST"
  authorization = "NONE"
}

resource "aws_api_gateway_integration" "test_client_report_resource_integration" {
  rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}"
  resource_id = "${aws_api_gateway_resource.test_client_report_resource.id}"
  http_method = "${aws_api_gateway_method.test_client_report_method.http_method}"
  type = "AWS"
  integration_http_method = "${aws_api_gateway_method.test_client_report_method.http_method}"
  uri = "arn:aws:apigateway:${var.region}:lambda:path/2015-03-31/functions/${aws_lambda_function.onlinetax_test_endpoint_lambda.arn}/invocations"
  request_templates = {
    "application/json" = "${file("${path.module}/generic_request_mapping_template.vm")}"
  }
}

resource "aws_api_gateway_method_response" "200" {
  rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}"
  resource_id = "${aws_api_gateway_resource.test_client_report_resource.id}"
  http_method = "${aws_api_gateway_method.test_client_report_method.http_method}"
  status_code = "200"
}

resource "aws_api_gateway_integration_response" "test_client_report_resource_integration_default_response" {
  rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}"
  resource_id = "${aws_api_gateway_resource.test_client_report_resource.id}"
  http_method = "${aws_api_gateway_method.test_client_report_method.http_method}"
  status_code = "${aws_api_gateway_method_response.200.status_code}"
  selection_pattern = ""
  depends_on = ["aws_api_gateway_integration.test_client_report_resource_integration"]
}

resource "aws_api_gateway_method_response" "500" {
  rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}"
  resource_id = "${aws_api_gateway_resource.test_client_report_resource.id}"
  http_method = "${aws_api_gateway_method.test_client_report_method.http_method}"
  status_code = "500"
}

resource "aws_api_gateway_integration_response" "test_client_report_resource_integration_error_response" {
  rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}"
  resource_id = "${aws_api_gateway_resource.test_client_report_resource.id}"
  http_method = "${aws_api_gateway_method.test_client_report_method.http_method}"
  status_code = "${aws_api_gateway_method_response.500.status_code}"
  selection_pattern = ".*?Error.*"
  depends_on = ["aws_api_gateway_integration.test_client_report_resource_integration"]
}

resource "aws_lambda_permission" "allow_api_gateway" {
    statement_id = "AllowExecutionFromAPIGateway"
    action = "lambda:InvokeFunction"
    function_name = "${aws_lambda_function.onlinetax_test_endpoint_lambda.arn}"
    principal = "apigateway.amazonaws.com"
    source_arn = "arn:aws:execute-api:${var.region}:${var.account_id}:${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}/*/${aws_api_gateway_integration.test_client_report_resource_integration.integration_http_method}${aws_api_gateway_resource.test_client_report_resource.path}"
    depends_on = ["aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api"]
}

#This is the part that doesn't seem to work. 
resource "aws_api_gateway_deployment" "qa5" {
  rest_api_id = "${aws_api_gateway_rest_api.online_tax_test_client_report_endpoint_api.id}"
  stage_name = "qa5"
  depends_on = ["aws_api_gateway_method.test_client_report_method"]
}

修改

在以下网址中添加了图表:

    digraph {
        compound = "true"
        newrank = "true"
        subgraph "root" {
            "[root] module.lambda.aws_api_gateway_deployment.qa5" [label = "aws_api_gateway_deployment.qa5", shape = "box"]
            "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" [label = "aws_api_gateway_integration.sbr_client_report_resource_integration", shape = "box"]
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" [label = "aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response", shape = "box"]
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" [label = "aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response", shape = "box"]
            "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" [label = "aws_api_gateway_method.sbr_client_report_method", shape = "box"]
            "[root] module.lambda.aws_api_gateway_method_response.200" [label = "aws_api_gateway_method_response.200", shape = "box"]
            "[root] module.lambda.aws_api_gateway_method_response.500" [label = "aws_api_gateway_method_response.500", shape = "box"]
            "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" [label = "aws_api_gateway_resource.sbr_client_report_resource", shape = "box"]
            "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" [label = "aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api", shape = "box"]
            "[root] module.lambda.aws_iam_role.onlinetax_sbr_endpoint_role" [label = "aws_iam_role.onlinetax_sbr_endpoint_role", shape = "box"]
            "[root] module.lambda.aws_iam_role_policy.publish_to_sns_policy" [label = "aws_iam_role_policy.publish_to_sns_policy", shape = "box"]
            "[root] module.lambda.aws_iam_role_policy.write_to_cloudwatch_policy" [label = "aws_iam_role_policy.write_to_cloudwatch_policy", shape = "box"]
            "[root] module.lambda.aws_lambda_function.onlinetax_sbr_endpoint_lambda" [label = "aws_lambda_function.onlinetax_sbr_endpoint_lambda", shape = "box"]
            "[root] module.lambda.aws_lambda_permission.allow_api_gateway" [label = "aws_lambda_permission.allow_api_gateway", shape = "box"]
            "[root] module.lambda.provider.aws" [label = "provider.aws", shape = "diamond"]
            "[root] module.sns.aws_sns_topic.online_tax_qa5_sbr_client_report" [label = "aws_sns_topic.online_tax_qa5_sbr_client_report", shape = "box"]
            "[root] module.sns.provider.aws" [label = "provider.aws", shape = "diamond"]
            "[root] provider.aws (disabled)" [label = "provider.aws (disabled)", shape = "diamond"]
            "[root] module.lambda.aws_api_gateway_deployment.qa5" -> "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method"
            "[root] module.lambda.aws_api_gateway_deployment.qa5" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api"
            "[root] module.lambda.aws_api_gateway_deployment.qa5" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" -> "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method"
            "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource"
            "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api"
            "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" -> "[root] module.lambda.aws_lambda_function.onlinetax_sbr_endpoint_lambda"
            "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" -> "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration"
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" -> "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method"
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" -> "[root] module.lambda.aws_api_gateway_method_response.200"
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource"
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api"
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_default_response" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" -> "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration"
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" -> "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method"
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" -> "[root] module.lambda.aws_api_gateway_method_response.500"
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource"
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api"
            "[root] module.lambda.aws_api_gateway_integration_response.sbr_client_report_resource_integration_error_response" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource"
            "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api"
            "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_api_gateway_method_response.200" -> "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method"
            "[root] module.lambda.aws_api_gateway_method_response.200" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource"
            "[root] module.lambda.aws_api_gateway_method_response.200" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api"
            "[root] module.lambda.aws_api_gateway_method_response.200" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_api_gateway_method_response.500" -> "[root] module.lambda.aws_api_gateway_method.sbr_client_report_method"
            "[root] module.lambda.aws_api_gateway_method_response.500" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource"
            "[root] module.lambda.aws_api_gateway_method_response.500" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api"
            "[root] module.lambda.aws_api_gateway_method_response.500" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api"
            "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" -> "[root] module.lambda.aws_lambda_function.onlinetax_sbr_endpoint_lambda"
            "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_iam_role.onlinetax_sbr_endpoint_role" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_iam_role_policy.publish_to_sns_policy" -> "[root] module.lambda.aws_iam_role.onlinetax_sbr_endpoint_role"
            "[root] module.lambda.aws_iam_role_policy.publish_to_sns_policy" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_iam_role_policy.publish_to_sns_policy" -> "[root] module.sns.aws_sns_topic.online_tax_qa5_sbr_client_report"
            "[root] module.lambda.aws_iam_role_policy.write_to_cloudwatch_policy" -> "[root] module.lambda.aws_iam_role.onlinetax_sbr_endpoint_role"
            "[root] module.lambda.aws_iam_role_policy.write_to_cloudwatch_policy" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_lambda_function.onlinetax_sbr_endpoint_lambda" -> "[root] module.lambda.aws_iam_role.onlinetax_sbr_endpoint_role"
            "[root] module.lambda.aws_lambda_function.onlinetax_sbr_endpoint_lambda" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.aws_lambda_permission.allow_api_gateway" -> "[root] module.lambda.aws_api_gateway_integration.sbr_client_report_resource_integration"
            "[root] module.lambda.aws_lambda_permission.allow_api_gateway" -> "[root] module.lambda.aws_api_gateway_resource.sbr_client_report_resource"
            "[root] module.lambda.aws_lambda_permission.allow_api_gateway" -> "[root] module.lambda.aws_api_gateway_rest_api.online_tax_sbr_client_report_endpoint_api"
            "[root] module.lambda.aws_lambda_permission.allow_api_gateway" -> "[root] module.lambda.aws_lambda_function.onlinetax_sbr_endpoint_lambda"
            "[root] module.lambda.aws_lambda_permission.allow_api_gateway" -> "[root] module.lambda.provider.aws"
            "[root] module.lambda.provider.aws" -> "[root] provider.aws (disabled)"
            "[root] module.sns.aws_sns_topic.online_tax_qa5_sbr_client_report" -> "[root] module.sns.provider.aws"
            "[root] module.sns.provider.aws" -> "[root] provider.aws (disabled)"
        }
}

图表中有其他资源,我在上面的tf文件中没有提供。它只有API GW有问题。顺便说一句,我能够从控制台测试API,它工作正常。我无法从我的localbox或postman执行它。

对我做错了什么的想法?

7 个答案:

答案 0 :(得分:9)

TF不会部署API,此链接可能会对您有所帮助:https://medium.com/coryodaniel/til-forcing-terraform-to-deploy-a-aws-api-gateway-deployment-ed36a9f60c1a

我通过添加变量deployed_at:

来修复我的
resource "aws_api_gateway_deployment" "api_ingest_deployment" {
  depends_on = ["aws_api_gateway_method.xxx",
                "aws_api_gateway_integration.yyy",
                "aws_api_gateway_integration.zzz",
                "aws_api_gateway_integration.www",
  ]
  rest_api_id = "${aws_api_gateway_rest_api.foo.id}"
  stage_name = "${var.environment}"

  variables {
    deployed_at = "${timestamp()}"
  }
}

缺点是如果以这种方式完成它将始终部署,即使没有变化

答案 1 :(得分:4)

在出现此错误时,这里的其他解决方案都无法为我服务:

BadRequestException: Active stages pointing to this deployment must be moved or deleted

This is the solution对我有用:

resource "aws_api_gateway_deployment" "api_deployment" {
  rest_api_id       = aws_api_gateway_rest_api.api.id
  stage_name        = "default"
  stage_description = "Deployed at ${timestamp()}"

  lifecycle {
    create_before_destroy = true
  }
}

在Terraform 0.12.24上测试

答案 2 :(得分:1)

如果您使用的是swagger模板和terraform ver> = 0.12,则可以如下所示为swagger文件提供MD5计算。效果很好。

resource "aws_api_gateway_deployment" "deploy_stage" {
  rest_api_id = aws_api_gateway_rest_api.product_api.id
  stage_name  = var.stage_name
  stage_description = md5(file("swagger_api.yml"))
}

答案 3 :(得分:1)

来自aws_api_gateway_deployment

resource "aws_api_gateway_deployment" "example" {
  rest_api_id = aws_api_gateway_rest_api.example.id

  triggers = {
    # NOTE: The configuration below will satisfy ordering considerations,
    #       but not pick up all future REST API changes. More advanced patterns
    #       are possible, such as using the filesha1() function against the
    #       Terraform configuration file(s) or removing the .id references to
    #       calculate a hash against whole resources. Be aware that using whole
    #       resources will show a difference after the initial implementation.
    #       It will stabilize to only change when resources change afterwards.
    redeployment = sha1(jsonencode([
      aws_api_gateway_resource.example.id,
      aws_api_gateway_method.example.id,
      aws_api_gateway_integration.example.id,
    ]))
  }

  lifecycle {
    create_before_destroy = true
  }
}

您需要定义应该触发新部署的触发器,我在没有 id 的情况下使用并且效果很好。

答案 4 :(得分:0)

通常,代码更改处于lambda级别。因此,您可以将lambda代码版本作为变量进行插值,并将其添加到您具有api部署的同一模块中。这样,它将仅在lambda代码更改时部署。

答案 5 :(得分:0)

有几件事需要注意。

  1. 要适当地依赖于此,以确保在执行集成和方法块之后(尤其是在有任何授权者的情况下)执行部署块。
  2. 将时间戳函数添加到变量中,以便在执行所有相关块后立即将其部署。

      resource "aws_api_gateway_deployment" "mydeployment" {
      depends_on =["aws_api_gateway_method.mymethod","aws_api_gateway_integration.myintegration"]
      rest_api_id = "${aws_api_gateway_rest_api.myapi.id}"
      stage_name = "dev"
      variables = {
         deployed_at = "${timestamp()}"
      }
    }
    

答案 6 :(得分:0)

遇到了同样的问题。 出现以下问题:

  1. ...) and then include the file you need:

我不得不将其设置为false,因为我将一个options方法添加到与get相同的uri中。当我尝试运行带有已启用标志的构建时,出现以下错误

创建API网关部署时出错:BadRequestException:未为方法定义集成

  1. 那之后我开始遇到问题

BadRequestException:指向此部署的活动阶段必须移动或删除

经过调查,我发现这与我的Terraform脚本中发生的自定义域映射有关。手动删除映射并运行Jenkins Job后,问题解决了。

  1. 我要做的最后一件事是在应用Terraform计划和terraform之前,在jenkins文件中使用以下脚本。我知道它是一个hack,但这是我能想到的最好的方法。

/ usr / local / bin / terraform destroy -target aws_api_gateway_base_path_mapping。 -auto-approve

这解决了问题。我检查了多个博客,他们提到将生命周期标志设置为true。但是由于它造成了上述问题,我无法做到。