From 0c73bdff8aa34bb8168ef1aaf5a5d9ed5ff495eb Mon Sep 17 00:00:00 2001
From: bertrand <bpinel@ippon.fr>
Date: Sun, 10 Feb 2019 17:32:15 +0100
Subject: [PATCH] Update terraform script to include S3 lambda code bucket and
 to correct some strage behaviour...

---
 cloud/lambda/lambda-jsonapi.zip | Bin 0 -> 3321 bytes
 cloud/terraform/api-gateway.tf  | 233 ++++++++++++++++++++++----------
 cloud/terraform/bucket.tf       |  11 ++
 cloud/terraform/lambda.tf       |   8 +-
 4 files changed, 181 insertions(+), 71 deletions(-)
 create mode 100644 cloud/lambda/lambda-jsonapi.zip

diff --git a/cloud/lambda/lambda-jsonapi.zip b/cloud/lambda/lambda-jsonapi.zip
new file mode 100644
index 0000000000000000000000000000000000000000..4c88a99dae208b141ce3294d9ead26ee0d7b52e3
GIT binary patch
literal 3321
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

literal 0
HcmV?d00001

diff --git a/cloud/terraform/api-gateway.tf b/cloud/terraform/api-gateway.tf
index 3030fb5..45bb796 100644
--- a/cloud/terraform/api-gateway.tf
+++ b/cloud/terraform/api-gateway.tf
@@ -26,7 +26,48 @@ resource "aws_api_gateway_method" "typePathGet" {
   http_method   = "GET"
   authorization = "NONE"
 }
-
+# OPTIONS on path /{type} for supporting CORS
+resource "aws_api_gateway_method" "typePathOptions" {
+  rest_api_id   = "${aws_api_gateway_rest_api.jsonapi.id}"
+  resource_id   = "${aws_api_gateway_resource.typePath.id}"
+  http_method   = "OPTIONS"
+  authorization = "NONE"
+}
+resource "aws_api_gateway_method_response" "typeOptions200" {
+    rest_api_id   = "${aws_api_gateway_rest_api.jsonapi.id}"
+    resource_id   = "${aws_api_gateway_resource.typePath.id}"
+    http_method   = "${aws_api_gateway_method.typePathOptions.http_method}"
+    status_code   = "200"
+    response_models {
+        "application/json" = "Empty"
+    }
+    response_parameters {
+        "method.response.header.Access-Control-Allow-Headers" = true,
+        "method.response.header.Access-Control-Allow-Methods" = true,
+        "method.response.header.Access-Control-Allow-Origin" = true
+    }
+}
+resource "aws_api_gateway_integration" "typeOptionsIntegration" {
+    rest_api_id   = "${aws_api_gateway_rest_api.jsonapi.id}"
+    resource_id   = "${aws_api_gateway_resource.typePath.id}"
+    http_method   = "${aws_api_gateway_method.typePathOptions.http_method}"
+    type          = "MOCK"
+    passthrough_behavior    = "WHEN_NO_TEMPLATES"
+    request_templates {
+      "application/json" = "{\"statusCode\": 200}"
+  }
+}
+resource "aws_api_gateway_integration_response" "typeOptionsIntegrationResponse" {
+    rest_api_id   = "${aws_api_gateway_rest_api.jsonapi.id}"
+    resource_id   = "${aws_api_gateway_resource.typePath.id}"
+    http_method   = "${aws_api_gateway_method.typePathOptions.http_method}"
+    status_code   = "${aws_api_gateway_method_response.typeOptions200.status_code}"
+    response_parameters = {
+        "method.response.header.Access-Control-Allow-Headers" = "'Content-Type,Access-Control-Allow-Origin,X-Amz-Date,Authorization,X-Requested-With,X-Requested-By,X-Api-Key,X-Amz-Security-Token'",
+        "method.response.header.Access-Control-Allow-Methods" = "'GET,OPTIONS,POST'",
+        "method.response.header.Access-Control-Allow-Origin" = "'*'"
+    }
+}
 # POST on path /{type}
 resource "aws_api_gateway_method" "typePathPost" {
   rest_api_id   = "${aws_api_gateway_rest_api.jsonapi.id}"
@@ -42,7 +83,48 @@ resource "aws_api_gateway_method" "typeIdPathGet" {
   http_method   = "GET"
   authorization = "NONE"
 }
-
+# OPTIONS on path /{type}/{id}
+resource "aws_api_gateway_method" "typeIdPathOptions" {
+  rest_api_id   = "${aws_api_gateway_rest_api.jsonapi.id}"
+  resource_id   = "${aws_api_gateway_resource.typeIdPath.id}"
+  http_method   = "OPTIONS"
+  authorization = "NONE"
+}
+resource "aws_api_gateway_method_response" "typeIdOptions200" {
+    rest_api_id   = "${aws_api_gateway_rest_api.jsonapi.id}"
+    resource_id   = "${aws_api_gateway_resource.typeIdPath.id}"
+    http_method   = "${aws_api_gateway_method.typeIdPathOptions.http_method}"
+    status_code   = "200"
+    response_models {
+        "application/json" = "Empty"
+    }
+    response_parameters {
+        "method.response.header.Access-Control-Allow-Headers" = true,
+        "method.response.header.Access-Control-Allow-Methods" = true,
+        "method.response.header.Access-Control-Allow-Origin" = true
+    }
+}
+resource "aws_api_gateway_integration" "typeIdOptionsIntegration" {
+    rest_api_id   = "${aws_api_gateway_rest_api.jsonapi.id}"
+    resource_id   = "${aws_api_gateway_resource.typeIdPath.id}"
+    http_method   = "${aws_api_gateway_method.typeIdPathOptions.http_method}"
+    type          = "MOCK"
+    passthrough_behavior    = "WHEN_NO_TEMPLATES"
+    request_templates {
+      "application/json" = "{\"statusCode\": 200}"
+  }
+}
+resource "aws_api_gateway_integration_response" "typeIdOptionsIntegrationResponse" {
+    rest_api_id   = "${aws_api_gateway_rest_api.jsonapi.id}"
+    resource_id   = "${aws_api_gateway_resource.typeIdPath.id}"
+    http_method   = "${aws_api_gateway_method.typeIdPathOptions.http_method}"
+    status_code   = "${aws_api_gateway_method_response.typeIdOptions200.status_code}"
+    response_parameters = {
+        "method.response.header.Access-Control-Allow-Headers" = "'Content-Type,Access-Control-Allow-Origin,X-Amz-Date,Authorization,X-Requested-With,X-Requested-By,X-Api-Key,X-Amz-Security-Token'",
+        "method.response.header.Access-Control-Allow-Methods" = "'GET,OPTIONS,DELETE,PATCH'",
+        "method.response.header.Access-Control-Allow-Origin" = "'*'"
+    }
+}
 # DELETE on path /{type}/{id}
 resource "aws_api_gateway_method" "typeIdPathDelete" {
   rest_api_id   = "${aws_api_gateway_rest_api.jsonapi.id}"
@@ -59,6 +141,8 @@ resource "aws_api_gateway_method" "typeIdPathPatch" {
   authorization = "NONE"
 }
 
+##############################################
+# GET on {type}
 # Setup Integration Request for GET on {type}
 resource "aws_api_gateway_integration" "lambdaJsonTypeGet" {
   rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
@@ -74,77 +158,15 @@ resource "aws_api_gateway_integration" "lambdaJsonTypeGet" {
     "application/json" = "${file("template.vm")}"
   }
 }
-
-# Setup Integration Request for POST on {type}
-resource "aws_api_gateway_integration" "lambdaJsonTypePost" {
-  rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
-  resource_id = "${aws_api_gateway_method.typePathPost.resource_id}"
-  http_method = "${aws_api_gateway_method.typePathPost.http_method}"
-
-  integration_http_method = "POST"
-  type                    = "AWS"
-  uri                     = "${aws_lambda_function.lambda-jsonapi.invoke_arn}"
-  # Transforms the incoming XML request to JSON
-  passthrough_behavior    = "WHEN_NO_TEMPLATES"
-  request_templates {
-    "application/json" = "${file("template.vm")}"
-  }
-}
-
-# Setup Integration Request for GET on {type}/{id}
-resource "aws_api_gateway_integration" "lambdaJsonTypeIdGet" {
-  rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
-  resource_id = "${aws_api_gateway_method.typeIdPathGet.resource_id}"
-  http_method = "${aws_api_gateway_method.typeIdPathGet.http_method}"
-
-  integration_http_method = "POST"
-  type                    = "AWS"
-  uri                     = "${aws_lambda_function.lambda-jsonapi.invoke_arn}"
-  # Transforms the incoming XML request to JSON
-  passthrough_behavior    = "WHEN_NO_TEMPLATES"
-  request_templates {
-    "application/json" = "${file("template.vm")}"
-  }
-}
-
-# Setup Integration Request for DELETE on {type}/{id}
-resource "aws_api_gateway_integration" "lambdaJsonTypeIdDelete" {
-  rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
-  resource_id = "${aws_api_gateway_method.typeIdPathDelete.resource_id}"
-  http_method = "${aws_api_gateway_method.typeIdPathDelete.http_method}"
-
-  integration_http_method = "POST"
-  type                    = "AWS"
-  uri                     = "${aws_lambda_function.lambda-jsonapi.invoke_arn}"
-  # Transforms the incoming XML request to JSON
-  passthrough_behavior    = "WHEN_NO_TEMPLATES"
-  request_templates {
-    "application/json" = "${file("template.vm")}"
-  }
-}
-
-# Setup Integration Request for PATCH on {type}/{id}
-resource "aws_api_gateway_integration" "lambdaJsonTypeIdPatch" {
-  rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
-  resource_id = "${aws_api_gateway_method.typeIdPathPatch.resource_id}"
-  http_method = "${aws_api_gateway_method.typeIdPathPatch.http_method}"
-
-  integration_http_method = "POST"
-  type                    = "AWS"
-  uri                     = "${aws_lambda_function.lambda-jsonapi.invoke_arn}"
-  # Transforms the incoming XML request to JSON
-  passthrough_behavior    = "WHEN_NO_TEMPLATES"
-  request_templates {
-    "application/json" = "${file("template.vm")}"
-  }
-}
-
 # Setup Integration Response for status code 200 and GET on {type}
 resource "aws_api_gateway_method_response" "200TypeGet" {
   rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
   resource_id = "${aws_api_gateway_method.typePathGet.resource_id}"
   http_method = "${aws_api_gateway_method.typePathGet.http_method}"
   status_code = "200"
+  response_parameters {
+        "method.response.header.Access-Control-Allow-Origin" = true
+    }
 }
 
 resource "aws_api_gateway_integration_response" "200TypeGetIntegrationResponse" {
@@ -155,8 +177,28 @@ resource "aws_api_gateway_integration_response" "200TypeGetIntegrationResponse"
   response_templates = {
     "application/json" = ""
   }
+  response_parameters {
+        "method.response.header.Access-Control-Allow-Origin" = "'*'"
+    }
+  depends_on = ["aws_api_gateway_integration.lambdaJsonTypeGet"]
 }
+##############################################
+# POST on {type}
+# Setup Integration Request for POST on {type}
+resource "aws_api_gateway_integration" "lambdaJsonTypePost" {
+  rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
+  resource_id = "${aws_api_gateway_method.typePathPost.resource_id}"
+  http_method = "${aws_api_gateway_method.typePathPost.http_method}"
 
+  integration_http_method = "POST"
+  type                    = "AWS"
+  uri                     = "${aws_lambda_function.lambda-jsonapi.invoke_arn}"
+  # Transforms the incoming XML request to JSON
+  passthrough_behavior    = "WHEN_NO_TEMPLATES"
+  request_templates {
+    "application/json" = "${file("template.vm")}"
+  }
+}
 # Setup Integration Response for status code 200 and POST on {type}
 resource "aws_api_gateway_method_response" "200TypePost" {
   rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
@@ -173,8 +215,25 @@ resource "aws_api_gateway_integration_response" "200TypePostIntegrationResponse"
   response_templates = {
     "application/json" = ""
   }
+  depends_on = ["aws_api_gateway_integration.lambdaJsonTypePost"]
 }
+##############################################
+# GET on {type}/{id}
+# Setup Integration Request for GET on {type}/{id}
+resource "aws_api_gateway_integration" "lambdaJsonTypeIdGet" {
+  rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
+  resource_id = "${aws_api_gateway_method.typeIdPathGet.resource_id}"
+  http_method = "${aws_api_gateway_method.typeIdPathGet.http_method}"
 
+  integration_http_method = "POST"
+  type                    = "AWS"
+  uri                     = "${aws_lambda_function.lambda-jsonapi.invoke_arn}"
+  # Transforms the incoming XML request to JSON
+  passthrough_behavior    = "WHEN_NO_TEMPLATES"
+  request_templates {
+    "application/json" = "${file("template.vm")}"
+  }
+}
 # Setup Integration Response for status code 200 and GET on {type}/{id}
 resource "aws_api_gateway_method_response" "200TypeIdGet" {
   rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
@@ -190,9 +249,26 @@ resource "aws_api_gateway_integration_response" "200TypeIdGetIntegrationResponse
   status_code = "${aws_api_gateway_method_response.200TypeIdGet.status_code}"
   response_templates = {
     "application/json" = ""
-  }
+  } 
+  depends_on=["aws_api_gateway_integration.lambdaJsonTypeIdGet"]
 }
+##############################################
+# DELETE on {type}/{id}
+# Setup Integration Request for DELETE on {type}/{id}
+resource "aws_api_gateway_integration" "lambdaJsonTypeIdDelete" {
+  rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
+  resource_id = "${aws_api_gateway_method.typeIdPathDelete.resource_id}"
+  http_method = "${aws_api_gateway_method.typeIdPathDelete.http_method}"
 
+  integration_http_method = "POST"
+  type                    = "AWS"
+  uri                     = "${aws_lambda_function.lambda-jsonapi.invoke_arn}"
+  # Transforms the incoming XML request to JSON
+  passthrough_behavior    = "WHEN_NO_TEMPLATES"
+  request_templates {
+    "application/json" = "${file("template.vm")}"
+  }
+}
 # Setup Integration Response for status code 200 and DELETE on {type}/{id}
 resource "aws_api_gateway_method_response" "200TypeIdDelete" {
   rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
@@ -209,8 +285,25 @@ resource "aws_api_gateway_integration_response" "200TypeIdDeleteIntegrationRespo
   response_templates = {
     "application/json" = ""
   }
+  depends_on= ["aws_api_gateway_integration.lambdaJsonTypeIdDelete"]
 }
+##############################################
+# PATCH on {type}/{id}
+# Setup Integration Request for PATCH on {type}/{id}
+resource "aws_api_gateway_integration" "lambdaJsonTypeIdPatch" {
+  rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
+  resource_id = "${aws_api_gateway_method.typeIdPathPatch.resource_id}"
+  http_method = "${aws_api_gateway_method.typeIdPathPatch.http_method}"
 
+  integration_http_method = "POST"
+  type                    = "AWS"
+  uri                     = "${aws_lambda_function.lambda-jsonapi.invoke_arn}"
+  # Transforms the incoming XML request to JSON
+  passthrough_behavior    = "WHEN_NO_TEMPLATES"
+  request_templates {
+    "application/json" = "${file("template.vm")}"
+  }
+}
 # Setup Integration Response for status code 200 and PATCH on {type}/{id}
 resource "aws_api_gateway_method_response" "200TypeIdPatch" {
   rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
@@ -218,7 +311,6 @@ resource "aws_api_gateway_method_response" "200TypeIdPatch" {
   http_method = "${aws_api_gateway_method.typeIdPathPatch.http_method}"
   status_code = "200"
 }
-
 resource "aws_api_gateway_integration_response" "200TypeIdPatchIntegrationResponse" {
   rest_api_id = "${aws_api_gateway_rest_api.jsonapi.id}"
   resource_id = "${aws_api_gateway_resource.typeIdPath.id}"
@@ -227,12 +319,15 @@ resource "aws_api_gateway_integration_response" "200TypeIdPatchIntegrationRespon
   response_templates = {
     "application/json" = ""
   }
+  depends_on = ["aws_api_gateway_integration.lambdaJsonTypeIdPatch"]
 }
 
 resource "aws_api_gateway_deployment" "jsonapiDeployment" {
   depends_on = [
+    "aws_api_gateway_integration.typeOptionsIntegration",
     "aws_api_gateway_integration.lambdaJsonTypeGet",
     "aws_api_gateway_integration.lambdaJsonTypePost",
+    "aws_api_gateway_integration.typeIdOptionsIntegration",
     "aws_api_gateway_integration.lambdaJsonTypeIdGet",
     "aws_api_gateway_integration.lambdaJsonTypeIdPatch",
     "aws_api_gateway_integration.lambdaJsonTypeIdDelete"
diff --git a/cloud/terraform/bucket.tf b/cloud/terraform/bucket.tf
index 830525d..0e7b86d 100644
--- a/cloud/terraform/bucket.tf
+++ b/cloud/terraform/bucket.tf
@@ -7,6 +7,17 @@ variable "bucket_name_staging" {
   default = "ember-aws-ehipster-staging"
 }
 
+resource "aws_s3_bucket" "lambda-bucket" {
+  bucket = "lambda-jsonapi-code-bucket"
+  acl    = "public-read"
+}
+resource "aws_s3_bucket_object" "lambda-bucket-code" {
+  bucket = "${aws_s3_bucket.lambda-bucket.bucket}"
+  key    = "v1.0.0/lambda-jsonapi.zip"
+  source = "../lambda/lambda-jsonapi.zip"
+  etag   = "${md5(file("../lambda/lambda-jsonapi.zip"))}"
+}
+
 resource "aws_s3_bucket" "production" {
   bucket = "${var.bucket_name_production}"
   acl    = "public-read"
diff --git a/cloud/terraform/lambda.tf b/cloud/terraform/lambda.tf
index 6f30758..27252ef 100644
--- a/cloud/terraform/lambda.tf
+++ b/cloud/terraform/lambda.tf
@@ -10,8 +10,8 @@ resource "aws_lambda_function" "lambda-jsonapi" {
   function_name = "lambda-jsonapi"
 
   # The bucket name as created before running terraform scripts with "aws s3api create-bucket"
-  s3_bucket = "lambda-jsonapi-code-bucket"
-  s3_key    = "v1.0.0/lambda-jsonapi.zip"
+  s3_bucket = "${aws_s3_bucket.lambda-bucket.bucket}"
+  s3_key    = "${aws_s3_bucket_object.lambda-bucket-code.key}"
 
   # "main" is the filename within the zip file (main.js) and "handler"
   # is the name of the property under which the handler function was
@@ -20,6 +20,8 @@ resource "aws_lambda_function" "lambda-jsonapi" {
   runtime = "nodejs8.10"
 
   role = "${aws_iam_role.lambda_jsonapi.arn}"
+
+  depends_on = ["aws_s3_bucket.lambda-bucket"]
 }
 
 
@@ -33,4 +35,6 @@ resource "aws_lambda_permission" "apigw" {
   # The /*/* portion grants access from any method on any resource
   # within the API Gateway "REST API".
   source_arn = "${aws_api_gateway_deployment.jsonapiDeployment.execution_arn}/*/*"
+
+  depends_on = ["aws_iam_role.lambda_jsonapi"]
 }
\ No newline at end of file
-- 
GitLab