2017-03-13 8 views
3

Ich versuche, einige AWS-Ressourcen, insbesondere ein API-Gateway, das mit einem Lambda verbunden ist, bereitzustellen. Ich benutze Terraform v0.8.8.Terraform - AWS - API-Gateway-Abhängigkeits-Rätsel

Ich habe ein Modul, das Bestimmungen der Lambda und die Lambda-Funktion ARN als eine Ausgabe liefert, die ich dann als Parameter auf die folgende API bereitstellen Gateway-Code Provisioning (die auf the example in the TF docs basiert):

provider "aws" { 
    access_key = "${var.access_key}" 
    secret_key = "${var.secret_key}" 
    region  = "${var.region}" 
} 

# Variables 
variable "myregion" { default = "eu-west-2" } 
variable "accountId" { default = "" } 
variable "lambdaArn" { default = "" } 
variable "stageName" { default = "lab" } 

# API Gateway 
resource "aws_api_gateway_rest_api" "api" { 
    name = "myapi" 
} 

resource "aws_api_gateway_method" "method" { 
    rest_api_id = "${aws_api_gateway_rest_api.api.id}" 
    resource_id = "${aws_api_gateway_rest_api.api.root_resource_id}" 
    http_method = "GET" 
    authorization = "NONE" 
} 

resource "aws_api_gateway_integration" "integration" { 
    rest_api_id    = "${aws_api_gateway_rest_api.api.id}" 
    resource_id    = "${aws_api_gateway_rest_api.api.root_resource_id}" 
    http_method    = "${aws_api_gateway_method.method.http_method}" 
    integration_http_method = "POST" 
    type     = "AWS" 
    uri      = "arn:aws:apigateway:${var.myregion}:lambda:path/2015-03-31/functions/${var.lambdaArn}/invocations" 
} 

# Lambda 
resource "aws_lambda_permission" "apigw_lambda" { 
    statement_id = "AllowExecutionFromAPIGateway" 
    action  = "lambda:InvokeFunction" 
    function_name = "${var.lambdaArn}" 
    principal  = "apigateway.amazonaws.com" 
    source_arn = "arn:aws:execute-api:${var.myregion}:${var.accountId}:${aws_api_gateway_rest_api.api.id}/*/${aws_api_gateway_method.method.http_method}/resourcepath/subresourcepath" 
} 

resource "aws_api_gateway_deployment" "deployment" { 
    rest_api_id = "${aws_api_gateway_rest_api.api.id}" 
    stage_name = "${var.stageName}" 
} 

Wenn ich die oben von Grund auf (dh, wenn keine der Ressourcen vorhanden sind) bekomme ich folgende Fehler ausgeführt:

Error applying plan: 

1 error(s) occurred: 

* aws_api_gateway_deployment.deployment: Error creating API Gateway Deployment: BadRequestException: No integration defined for method 
    status code: 400, request id: 15604135-03f5-11e7-8321-f5a75dc2b0a3 

Terraform does not automatically rollback in the face of errors. 
Instead, your Terraform state file has been partially updated with 
any resources that successfully completed. Please address the error 
above and apply again to incrementally change your infrastructure. 

Wenn ich eine zweite TF-Anwendung ausführen erfolgreich gilt konsequent, aber jedes Mal, wenn ich zu zerstören ich dann erhalten der obige Fehler bei der ersten Anwendung.

Das bin ich verursacht, wenn sich zu fragen, eine Abhängigkeit ist, die ich brauche irgendwo ausdrücklich zu erklären, ich #7486 entdeckt, die ein ähnliches Muster beschreibt (wenn auch in einem aws_api_gateway_integration_response beziehen und nicht als aws_api_gateway_deployment). Ich habe versucht, manuell eine explizite Abhängigkeit von aws_api_gateway_deployment zu hinzuzufügen, aber dies hatte keine Auswirkungen.

Dankbar für irgendwelche Gedanken, einschließlich, ob dies in der Tat ein TF-Bug sein kann, in welchem ​​Fall ich es im Issue Tracker ersehe. Ich dachte, ich würde mich vorher bei der Community erkundigen, falls ich etwas Offensichtliches vermisse.

Vielen Dank,

Edd

P. S. Ich habe this question on the Terraform user group gefragt, aber das scheint sehr wenig Antworten zu bekommen, ich bin noch nicht in der Lage, die Ursache des Problems herauszufinden und frage mich jetzt.

+0

Welche Version von Terraform verwenden Sie? – user3610360

+0

Hey, @ user3610360 - Ich benutze v0.8.8 –

Antwort

7

Mit der expliziten Abhängigkeitsdeklaration haben Sie recht.

Normalerweise würde Terraform in der Lage sein, die Beziehungen zu ermitteln und die Operationen zum Erstellen/Aktualisieren/Löschen entsprechend zu planen - dies ist hauptsächlich aufgrund der Interpolationsmechanismen unter der Haube möglich (${resource_type.ref_name.attribute}). Sie können die sich darauf beziehenden Beziehungen in einem Diagramm über terraform graph anzeigen. In diesem speziellen Fall gibt es keine direkte Beziehung zwischen API-Gatewaybereitstellungen und -Integrationen. Dies bedeutet, dass die API-Schnittstelle für die Verwaltung von API-Gatewayressourcen nicht auf die Integrations-ID oder Ähnliches verweisen muss, um die Bereitstellung und die Ressource api_gateway_deployment zu erstellen Turn erfordert das auch nicht.

Die documentation for aws_api_gateway_deployment erwähnt diesen Vorbehalt am Anfang der Seite. Zugegeben, die Implementierung erfordert nicht nur die Methode, sondern auch die Integration.

Hier ist, wie Sie Ihren Code ändern können, um es zu bekommen:

resource "aws_api_gateway_deployment" "deployment" { 
    rest_api_id = "${aws_api_gateway_rest_api.api.id}" 
    stage_name = "${var.stageName}" 
    depends_on = ["aws_api_gateway_method.method", "aws_api_gateway_integration.integration"] 
} 

Theoretisch die "aws_api_gateway_method.method" ist überflüssig, da die Integration bereits die Methode in der Config verweist:

http_method    = "${aws_api_gateway_method.method.http_method}" 

so wird es sein geplant für die Erstellung/Aktualisierung vor der Integration in beide Richtungen, aber wenn Sie das zu etwas wie

http_method    = "GET" 
ändern sollten

dann würde es notwendig werden.

Ich habe submitted PR, um die Dokumente entsprechend zu aktualisieren.

+0

Große Antwort, funktioniert perfekt, vielen Dank sowohl für die Beispiel-Code-Fix und die Erklärung @ Radek-Simko –