From 0a2591221677c9f16cc3decd2ca563d310983c0d Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Fri, 6 Oct 2023 14:41:40 +0200 Subject: [PATCH 01/20] #1445 first implementation of terraform core example --- .gitignore | 5 +- examples/pom.xml | 1 + examples/powertools-examples-core/README.md | 1 + .../terraform/README.md | 27 +++ .../terraform/infra/api-gateway.tf | 92 ++++++++ .../terraform/infra/lambda.tf | 112 ++++++++++ .../terraform/infra/main.tf | 5 + .../terraform/infra/variables.tf | 14 ++ .../terraform/main.tf | 4 + .../terraform/pom.xml | 209 ++++++++++++++++++ .../src/main/java/helloworld/App.java | 105 +++++++++ .../src/main/java/helloworld/AppStream.java | 38 ++++ .../terraform/src/main/resources/log4j2.xml | 16 ++ .../src/test/java/helloworld/AppTest.java | 59 +++++ 14 files changed, 687 insertions(+), 1 deletion(-) create mode 100644 examples/powertools-examples-core/terraform/README.md create mode 100644 examples/powertools-examples-core/terraform/infra/api-gateway.tf create mode 100644 examples/powertools-examples-core/terraform/infra/lambda.tf create mode 100644 examples/powertools-examples-core/terraform/infra/main.tf create mode 100644 examples/powertools-examples-core/terraform/infra/variables.tf create mode 100644 examples/powertools-examples-core/terraform/main.tf create mode 100644 examples/powertools-examples-core/terraform/pom.xml create mode 100644 examples/powertools-examples-core/terraform/src/main/java/helloworld/App.java create mode 100644 examples/powertools-examples-core/terraform/src/main/java/helloworld/AppStream.java create mode 100644 examples/powertools-examples-core/terraform/src/main/resources/log4j2.xml create mode 100644 examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java diff --git a/.gitignore b/.gitignore index b404d2cb2..b965bf1aa 100644 --- a/.gitignore +++ b/.gitignore @@ -108,4 +108,7 @@ example/HelloWorldFunction/build /example/.gradle/ /example/.java-version .gradle -build/ \ No newline at end of file +build/ +.terraform +.terraform.lock.hcl +terraform.tfstate* \ No newline at end of file diff --git a/examples/pom.xml b/examples/pom.xml index 810ec1b36..900f095f8 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -33,6 +33,7 @@ powertools-examples-core/cdk/app powertools-examples-core/cdk/infra powertools-examples-core/serverless + powertools-examples-core/terraform powertools-examples-idempotency powertools-examples-parameters powertools-examples-serialization diff --git a/examples/powertools-examples-core/README.md b/examples/powertools-examples-core/README.md index 1d1dd031f..a0ffb125d 100644 --- a/examples/powertools-examples-core/README.md +++ b/examples/powertools-examples-core/README.md @@ -10,6 +10,7 @@ We provide examples for the following infrastructure-as-code tools: * [AWS SAM](sam/) * [AWS CDK](cdk/) * [Serverless framework](serverless/) +* [Terraform](terraform/) We also provide an example showing the integration of SAM, Powertools, and Gradle: diff --git a/examples/powertools-examples-core/terraform/README.md b/examples/powertools-examples-core/terraform/README.md new file mode 100644 index 000000000..ba03b8107 --- /dev/null +++ b/examples/powertools-examples-core/terraform/README.md @@ -0,0 +1,27 @@ +# Powertools for AWS Lambda (Java) - Core Utilities Example with Terraform + +This project demonstrates the Lambda for Powertools Java module deployed using [Terraform](https://www.terraform.io/). +For general information on the deployed example itself, you can refer to the parent [README](../README.md). +To install Terraform if you don't have it yet, you can follow the [Install Terraform Guide](https://developer.hashicorp.com/terraform/downloads?product_intent=terraform). + +## Configuration +Serverless Framework uses [serverless.yml](./serverless.yml) to define the application's AWS resources. +This file defines the Lambda function to be deployed as well as API Gateway for it. + +It is a [Maven](https://maven.apache.org/) based project, so you can open this project with any Maven compatible Java IDE to build and run tests. + + +## Deploy the sample application + +To deploy the app, simply run the following commands: +```bash +terraform init +terraform apply +``` + +## Useful commands + +To destroy the app +```bash +terraform destroy +``` diff --git a/examples/powertools-examples-core/terraform/infra/api-gateway.tf b/examples/powertools-examples-core/terraform/infra/api-gateway.tf new file mode 100644 index 000000000..d1ddd0275 --- /dev/null +++ b/examples/powertools-examples-core/terraform/infra/api-gateway.tf @@ -0,0 +1,92 @@ +resource "aws_api_gateway_rest_api" "hello_world_api" { + name = "hello_world_api" + description = "API Gateway endpoint URL for Prod stage for Hello World function" +} + +resource "aws_api_gateway_resource" "hello_resource" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + parent_id = "${aws_api_gateway_rest_api.hello_world_api.root_resource_id}" + path_part = "hello" +} + +resource "aws_api_gateway_resource" "hello_stream_resource" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + parent_id = "${aws_api_gateway_rest_api.hello_world_api.root_resource_id}" + path_part = "hellostream" +} + +resource "aws_api_gateway_method" "hello_get_method" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + resource_id = "${aws_api_gateway_resource.hello_resource.id}" + http_method = "GET" + authorization = "NONE" +} + +resource "aws_api_gateway_method" "hello_stream_get_method" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + resource_id = "${aws_api_gateway_resource.hello_stream_resource.id}" + http_method = "GET" + authorization = "NONE" +} + +resource "aws_api_gateway_integration" "java_lambda_integration" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + resource_id = "${aws_api_gateway_resource.hello_resource.id}" + http_method = "${aws_api_gateway_method.hello_get_method.http_method}" + + integration_http_method = "POST" + type = "AWS_PROXY" + uri = "${aws_lambda_function.hello_world_lambda.invoke_arn}" +} + +resource "aws_api_gateway_integration" "java_stream_lambda_integration" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + resource_id = "${aws_api_gateway_resource.hello_stream_resource.id}" + http_method = "${aws_api_gateway_method.hello_stream_get_method.http_method}" + + integration_http_method = "POST" + type = "AWS_PROXY" + uri = "${aws_lambda_function.hello_world_stream_lambda.invoke_arn}" +} + +resource "aws_api_gateway_deployment" "prod_deployment" { + depends_on = [aws_api_gateway_integration.java_lambda_integration, aws_api_gateway_integration.java_stream_lambda_integration] + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + stage_name = "prod" +} + +# Allows API gateway to invoke lambda +resource "aws_lambda_permission" "hello_world_lambda_invoke" { + statement_id = "AllowAPIGatewayInvoke" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.hello_world_lambda.function_name}" + principal = "apigateway.amazonaws.com" + source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/${aws_api_gateway_deployment.prod_deployment.stage_name}/GET/hello" +} + +# Allows API gateway to invoke lambda +resource "aws_lambda_permission" "hello_world_lambda_testinvoke" { + statement_id = "AllowAPIGatewayTestInvoke" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.hello_world_lambda.function_name}" + principal = "apigateway.amazonaws.com" + source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/test-invoke-stage/GET/hello" +} + +# Allows API gateway to invoke lambda +resource "aws_lambda_permission" "hello_world_stream_lambda_invoke" { + statement_id = "AllowAPIGatewayInvoke" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.hello_world_stream_lambda.function_name}" + principal = "apigateway.amazonaws.com" + source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/${aws_api_gateway_deployment.prod_deployment.stage_name}/GET/hellostream" +} + +# Allows API gateway to invoke lambda +resource "aws_lambda_permission" "hello_world_stream_lambda_testinvoke" { + statement_id = "AllowAPIGatewayTestInvoke" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.hello_world_stream_lambda.function_name}" + principal = "apigateway.amazonaws.com" + source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/test-invoke-stage/GET/hellostream" +} diff --git a/examples/powertools-examples-core/terraform/infra/lambda.tf b/examples/powertools-examples-core/terraform/infra/lambda.tf new file mode 100644 index 000000000..67c74184f --- /dev/null +++ b/examples/powertools-examples-core/terraform/infra/lambda.tf @@ -0,0 +1,112 @@ +resource "aws_lambda_function" "hello_world_lambda" { + runtime = "java11" + filename = "target/helloworld-lambda.jar" + source_code_hash = filebase64sha256("target/helloworld-lambda.jar") + function_name = "hello_world_lambda" + + handler = "helloworld.App" + description = "Powertools example, deployed by Terraform" + timeout = 20 + memory_size = 512 + role = "${aws_iam_role.iam_role_for_lambda.arn}" + environment { + variables = { + POWERTOOLS_LOG_LEVEL = "INFO" + POWERTOOLS_LOGGER_SAMPLE_RATE = "0.1" + POWERTOOLS_LOGGER_LOG_EVENT = "true" + POWERTOOLS_METRICS_NAMESPACE = "Coreutilities" + } + } + tracing_config { + mode = "Active" + } + depends_on = [aws_cloudwatch_log_group.log_group] +} + +resource "aws_lambda_function" "hello_world_stream_lambda" { + runtime = "java11" + filename = "target/helloworld-lambda.jar" + source_code_hash = filebase64sha256("target/helloworld-lambda.jar") + function_name = "hello_world_stream_lambda" + + handler = "helloworld.AppStream" + description = "Powertools example, deployed by Terraform" + timeout = 20 + memory_size = 512 + role = "${aws_iam_role.iam_role_for_lambda.arn}" + environment { + variables = { + POWERTOOLS_LOG_LEVEL = "INFO" + POWERTOOLS_LOGGER_SAMPLE_RATE = "0.7" + POWERTOOLS_LOGGER_LOG_EVENT = "true" + POWERTOOLS_METRICS_NAMESPACE = "Coreutilities" + POWERTOOLS_SERVICE_NAME = "hello" + } + } + tracing_config { + mode = "Active" + } + depends_on = [aws_cloudwatch_log_group.log_group] +} + +# Create a log group for the lambda +resource "aws_cloudwatch_log_group" "log_group" { + name = "/aws/lambda/hello_world_lambda" +} + +# Create a log group for the lambda +resource "aws_cloudwatch_log_group" "log_group_stream" { + name = "/aws/lambda/hello_world_stream_lambda" +} + +# lambda role +resource "aws_iam_role" "iam_role_for_lambda" { + name = "lambda-invoke-role" + assume_role_policy = < + 4.0.0 + + software.amazon.lambda.examples + 1.18.0-SNAPSHOT + powertools-examples-core-terraform + jar + + Powertools for AWS Lambda (Java) library Examples - Core + + + 2.20.0 + 1.8 + 1.8 + + + + + software.amazon.lambda + powertools-tracing + ${project.version} + + + software.amazon.lambda + powertools-logging + ${project.version} + + + software.amazon.lambda + powertools-metrics + ${project.version} + + + com.amazonaws + aws-lambda-java-core + 1.2.2 + + + com.amazonaws + aws-lambda-java-events + 3.11.2 + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + + junit + junit + 4.13.2 + test + + + + + helloworld-lambda + + + dev.aspectj + aspectj-maven-plugin + 1.13.1 + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-tracing + + + software.amazon.lambda + powertools-logging + + + software.amazon.lambda + powertools-metrics + + + + + + + compile + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.0 + + + package + + shade + + + + + + + + + + + + com.github.edwgiz + maven-shade-plugin.log4j2-cachefile-transformer + 2.15 + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + + + + jdk8 + + (,11) + + + 1.9.7 + + + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + + + dev.aspectj + aspectj-maven-plugin + ${aspectj.plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-tracing + + + software.amazon.lambda + powertools-logging + + + software.amazon.lambda + powertools-metrics + + + + + + + compile + test-compile + + + + + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + + + + diff --git a/examples/powertools-examples-core/terraform/src/main/java/helloworld/App.java b/examples/powertools-examples-core/terraform/src/main/java/helloworld/App.java new file mode 100644 index 000000000..dacd7f1d4 --- /dev/null +++ b/examples/powertools-examples-core/terraform/src/main/java/helloworld/App.java @@ -0,0 +1,105 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. + * Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package helloworld; + +import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger; +import static software.amazon.lambda.powertools.metrics.MetricsUtils.withSingleMetric; +import static software.amazon.lambda.powertools.tracing.TracingUtils.putMetadata; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import software.amazon.cloudwatchlogs.emf.model.DimensionSet; +import software.amazon.cloudwatchlogs.emf.model.Unit; +import software.amazon.lambda.powertools.logging.Logging; +import software.amazon.lambda.powertools.logging.LoggingUtils; +import software.amazon.lambda.powertools.metrics.Metrics; +import software.amazon.lambda.powertools.tracing.CaptureMode; +import software.amazon.lambda.powertools.tracing.Tracing; +import software.amazon.lambda.powertools.tracing.TracingUtils; + +/** + * Handler for requests to Lambda function. + */ +public class App implements RequestHandler { + private final static Logger log = LogManager.getLogger(App.class); + + // This is controlled by POWERTOOLS_LOGGER_SAMPLE_RATE environment variable + // @Logging(logEvent = true, samplingRate = 0.7) + // This is controlled by POWERTOOLS_METRICS_NAMESPACE environment variable + // @Metrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true) + // This is controlled by POWERTOOLS_TRACER_CAPTURE_ERROR environment variable + @Tracing(captureMode = CaptureMode.RESPONSE_AND_ERROR) + public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) { + Map headers = new HashMap<>(); + + headers.put("Content-Type", "application/json"); + headers.put("X-Custom-Header", "application/json"); + + metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); + + withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", (metric) -> + { + metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); + metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); + }); + + LoggingUtils.appendKey("test", "willBeLogged"); + + APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent() + .withHeaders(headers); + try { + final String pageContents = this.getPageContents("https://checkip.amazonaws.com"); + log.info(pageContents); + TracingUtils.putAnnotation("Test", "New"); + String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents); + + TracingUtils.withSubsegment("loggingResponse", subsegment -> + { + String sampled = "log something out"; + log.info(sampled); + log.info(output); + }); + + log.info("After output"); + return response + .withStatusCode(200) + .withBody(output); + } catch (RuntimeException | IOException e) { + return response + .withBody("{}") + .withStatusCode(500); + } + } + + @Tracing(namespace = "getPageContents", captureMode = CaptureMode.DISABLED) + private String getPageContents(String address) throws IOException { + URL url = new URL(address); + putMetadata("getPageContents", address); + try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) { + return br.lines().collect(Collectors.joining(System.lineSeparator())); + } + } +} diff --git a/examples/powertools-examples-core/terraform/src/main/java/helloworld/AppStream.java b/examples/powertools-examples-core/terraform/src/main/java/helloworld/AppStream.java new file mode 100644 index 000000000..401ef8c48 --- /dev/null +++ b/examples/powertools-examples-core/terraform/src/main/java/helloworld/AppStream.java @@ -0,0 +1,38 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. + * Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package helloworld; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestStreamHandler; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; +import software.amazon.lambda.powertools.logging.Logging; +import software.amazon.lambda.powertools.metrics.Metrics; + +public class AppStream implements RequestStreamHandler { + private static final ObjectMapper mapper = new ObjectMapper(); + + @Override + @Logging(logEvent = true) + @Metrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true) + public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException { + Map map = mapper.readValue(input, Map.class); + + System.out.println(map.size()); + } +} diff --git a/examples/powertools-examples-core/terraform/src/main/resources/log4j2.xml b/examples/powertools-examples-core/terraform/src/main/resources/log4j2.xml new file mode 100644 index 000000000..0cc0953f0 --- /dev/null +++ b/examples/powertools-examples-core/terraform/src/main/resources/log4j2.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java new file mode 100644 index 000000000..70dad8d71 --- /dev/null +++ b/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. + * Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package helloworld; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import com.amazonaws.xray.AWSXRay; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class AppTest { + + @Before + public void setup() { + if (null == System.getenv("LAMBDA_TASK_ROOT")) { + AWSXRay.beginSegment("test"); + } + } + + @After + public void tearDown() { + if (AWSXRay.getCurrentSubsegmentOptional().isPresent()) { + AWSXRay.endSubsegment(); + } + + if (null == System.getenv("LAMBDA_TASK_ROOT")) { + AWSXRay.endSegment(); + } + } + + @Test + public void successfulResponse() { + App app = new App(); + APIGatewayProxyResponseEvent result = app.handleRequest(null, null); + assertEquals(result.getStatusCode().intValue(), 200); + assertEquals(result.getHeaders().get("Content-Type"), "application/json"); + String content = result.getBody(); + assertNotNull(content); + assertTrue(content.contains("\"message\"")); + assertTrue(content.contains("\"hello world\"")); + assertTrue(content.contains("\"location\"")); + } +} From 1745a6ba3622721beaf52e67194a605b0ab48e06 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Fri, 6 Oct 2023 14:54:28 +0200 Subject: [PATCH 02/20] #1445 updated readme to include maven instructions --- .gitignore | 3 +-- examples/powertools-examples-core/terraform/README.md | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index b965bf1aa..6615ac729 100644 --- a/.gitignore +++ b/.gitignore @@ -109,6 +109,5 @@ example/HelloWorldFunction/build /example/.java-version .gradle build/ -.terraform -.terraform.lock.hcl +.terraform* terraform.tfstate* \ No newline at end of file diff --git a/examples/powertools-examples-core/terraform/README.md b/examples/powertools-examples-core/terraform/README.md index ba03b8107..27d47fbbb 100644 --- a/examples/powertools-examples-core/terraform/README.md +++ b/examples/powertools-examples-core/terraform/README.md @@ -16,7 +16,7 @@ It is a [Maven](https://maven.apache.org/) based project, so you can open this p To deploy the app, simply run the following commands: ```bash terraform init -terraform apply +mvn package && terraform apply ``` ## Useful commands From 8bf546a0a06a742adf379b2d4ce9cc37c97c4c15 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Fri, 13 Oct 2023 10:03:19 +0200 Subject: [PATCH 03/20] #1458 fixed readme typo + removed lambda env configuration + output api URL --- .../terraform/README.md | 2 +- .../terraform/infra/api-gateway.tf | 2 ++ .../terraform/infra/lambda.tf | 17 ----------------- .../powertools-examples-core/terraform/main.tf | 5 +++++ 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/examples/powertools-examples-core/terraform/README.md b/examples/powertools-examples-core/terraform/README.md index 27d47fbbb..71c78d437 100644 --- a/examples/powertools-examples-core/terraform/README.md +++ b/examples/powertools-examples-core/terraform/README.md @@ -5,7 +5,7 @@ For general information on the deployed example itself, you can refer to the par To install Terraform if you don't have it yet, you can follow the [Install Terraform Guide](https://developer.hashicorp.com/terraform/downloads?product_intent=terraform). ## Configuration -Serverless Framework uses [serverless.yml](./serverless.yml) to define the application's AWS resources. +Terraform uses [main.tf](./main.tf) to define the application's AWS resources. This file defines the Lambda function to be deployed as well as API Gateway for it. It is a [Maven](https://maven.apache.org/) based project, so you can open this project with any Maven compatible Java IDE to build and run tests. diff --git a/examples/powertools-examples-core/terraform/infra/api-gateway.tf b/examples/powertools-examples-core/terraform/infra/api-gateway.tf index d1ddd0275..dba1c3616 100644 --- a/examples/powertools-examples-core/terraform/infra/api-gateway.tf +++ b/examples/powertools-examples-core/terraform/infra/api-gateway.tf @@ -90,3 +90,5 @@ resource "aws_lambda_permission" "hello_world_stream_lambda_testinvoke" { principal = "apigateway.amazonaws.com" source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/test-invoke-stage/GET/hellostream" } + +output "invoke" {value=aws_api_gateway_deployment.prod_deployment.invoke_url} \ No newline at end of file diff --git a/examples/powertools-examples-core/terraform/infra/lambda.tf b/examples/powertools-examples-core/terraform/infra/lambda.tf index 67c74184f..abebccf54 100644 --- a/examples/powertools-examples-core/terraform/infra/lambda.tf +++ b/examples/powertools-examples-core/terraform/infra/lambda.tf @@ -9,14 +9,6 @@ resource "aws_lambda_function" "hello_world_lambda" { timeout = 20 memory_size = 512 role = "${aws_iam_role.iam_role_for_lambda.arn}" - environment { - variables = { - POWERTOOLS_LOG_LEVEL = "INFO" - POWERTOOLS_LOGGER_SAMPLE_RATE = "0.1" - POWERTOOLS_LOGGER_LOG_EVENT = "true" - POWERTOOLS_METRICS_NAMESPACE = "Coreutilities" - } - } tracing_config { mode = "Active" } @@ -34,15 +26,6 @@ resource "aws_lambda_function" "hello_world_stream_lambda" { timeout = 20 memory_size = 512 role = "${aws_iam_role.iam_role_for_lambda.arn}" - environment { - variables = { - POWERTOOLS_LOG_LEVEL = "INFO" - POWERTOOLS_LOGGER_SAMPLE_RATE = "0.7" - POWERTOOLS_LOGGER_LOG_EVENT = "true" - POWERTOOLS_METRICS_NAMESPACE = "Coreutilities" - POWERTOOLS_SERVICE_NAME = "hello" - } - } tracing_config { mode = "Active" } diff --git a/examples/powertools-examples-core/terraform/main.tf b/examples/powertools-examples-core/terraform/main.tf index c672bc769..67fb6b104 100644 --- a/examples/powertools-examples-core/terraform/main.tf +++ b/examples/powertools-examples-core/terraform/main.tf @@ -2,3 +2,8 @@ module "powertools_for_java_lambda" { source = "./infra/" } + +output "api_url" { + value = module.powertools_for_java_lambda.invoke + description = "URL where the API gateway can be invoked" +} \ No newline at end of file From 511fae3770caf4d9cabf844a60ece087fc8ef6e5 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Fri, 13 Oct 2023 16:29:41 +0200 Subject: [PATCH 04/20] #1458 added tflint and tf validate to the PR build --- .github/workflows/pr_build.yml | 20 +++++++++++++++++++ .../terraform/.tflint.hcl | 3 +++ 2 files changed, 23 insertions(+) create mode 100644 examples/powertools-examples-core/terraform/.tflint.hcl diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 73ae67553..fec25276b 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -68,6 +68,26 @@ jobs: run: | cd examples/powertools-examples-core/gradle ./gradlew build + - name: Setup Terraform + if: ${{ matrix.java == '11' }} + uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 #v2.0.3 + - name: Terraform validate + if: ${{ matrix.java == '11' }} + run: | + terraform -version + cd examples/powertools-examples-core/terraform + terraform init + terraform validate + - name: Setup Terraform lint + if: ${{ matrix.java == '11' }} + uses: terraform-linters/setup-tflint@a5a1af8c6551fb10c53f1cd4ba62359f1973746f # v3.1.1 + - name: Terraform lint + if: ${{ matrix.java == '11' }} + run: | + tflint --version + cd examples/powertools-examples-core/terraform + tflint --init + tflint -f compact - name: Upload coverage to Codecov uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 if: ${{ matrix.java == '11' }} # publish results once diff --git a/examples/powertools-examples-core/terraform/.tflint.hcl b/examples/powertools-examples-core/terraform/.tflint.hcl new file mode 100644 index 000000000..18e69352b --- /dev/null +++ b/examples/powertools-examples-core/terraform/.tflint.hcl @@ -0,0 +1,3 @@ +rule "terraform_required_version" { + enabled = false +} \ No newline at end of file From a93a086d50f0277e780b35aeccb2354521f19b92 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Fri, 13 Oct 2023 17:13:00 +0200 Subject: [PATCH 05/20] #1458 tf plan, removed tf aws variables, removed xray from AppTest --- .github/workflows/pr_build.yml | 1 + .../terraform/infra/main.tf | 5 ----- .../terraform/infra/variables.tf | 14 ------------- .../src/test/java/helloworld/AppTest.java | 21 ------------------- 4 files changed, 1 insertion(+), 40 deletions(-) delete mode 100644 examples/powertools-examples-core/terraform/infra/main.tf delete mode 100644 examples/powertools-examples-core/terraform/infra/variables.tf diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index fec25276b..76a7620fe 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -78,6 +78,7 @@ jobs: cd examples/powertools-examples-core/terraform terraform init terraform validate + terraform plan - name: Setup Terraform lint if: ${{ matrix.java == '11' }} uses: terraform-linters/setup-tflint@a5a1af8c6551fb10c53f1cd4ba62359f1973746f # v3.1.1 diff --git a/examples/powertools-examples-core/terraform/infra/main.tf b/examples/powertools-examples-core/terraform/infra/main.tf deleted file mode 100644 index 4fc5d91b1..000000000 --- a/examples/powertools-examples-core/terraform/infra/main.tf +++ /dev/null @@ -1,5 +0,0 @@ -provider "aws" { - access_key = "${var.aws_access_key}" - secret_key = "${var.aws_secret_key}" - region = "${var.region}" -} diff --git a/examples/powertools-examples-core/terraform/infra/variables.tf b/examples/powertools-examples-core/terraform/infra/variables.tf deleted file mode 100644 index f069c7b95..000000000 --- a/examples/powertools-examples-core/terraform/infra/variables.tf +++ /dev/null @@ -1,14 +0,0 @@ -variable "aws_access_key" { - # set aws access key - default = "" -} - -variable "aws_secret_key" { - # set aws secret key - default = "" -} - -variable "region" { - # set aws region - default = "" -} \ No newline at end of file diff --git a/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java index 70dad8d71..0ca4f264d 100644 --- a/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java +++ b/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java @@ -19,31 +19,10 @@ import static org.junit.Assert.assertTrue; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; -import com.amazonaws.xray.AWSXRay; -import org.junit.After; -import org.junit.Before; import org.junit.Test; public class AppTest { - @Before - public void setup() { - if (null == System.getenv("LAMBDA_TASK_ROOT")) { - AWSXRay.beginSegment("test"); - } - } - - @After - public void tearDown() { - if (AWSXRay.getCurrentSubsegmentOptional().isPresent()) { - AWSXRay.endSubsegment(); - } - - if (null == System.getenv("LAMBDA_TASK_ROOT")) { - AWSXRay.endSegment(); - } - } - @Test public void successfulResponse() { App app = new App(); From db01cae8eb69c84952bbe87861f7a1baf474d3c2 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Fri, 13 Oct 2023 17:22:29 +0200 Subject: [PATCH 06/20] #1458 tentative fix -> tf validate fails without proper AWS credentials --- .github/workflows/pr_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 76a7620fe..c9a1a6e23 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -76,7 +76,7 @@ jobs: run: | terraform -version cd examples/powertools-examples-core/terraform - terraform init + terraform init -backend=false terraform validate terraform plan - name: Setup Terraform lint From 9019e738616d51f960ed7ba55839c689d37f518e Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Mon, 16 Oct 2023 13:40:13 +0200 Subject: [PATCH 07/20] #1458 add LAMBDA_TASK_ROOT at pom level, removed tf plan for now, changed tf providers to pass tf validate --- .github/workflows/pr_build.yml | 1 - .../powertools-examples-core/terraform/main.tf | 14 ++++++++++++++ .../powertools-examples-core/terraform/pom.xml | 10 ++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index c9a1a6e23..53346fa69 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -78,7 +78,6 @@ jobs: cd examples/powertools-examples-core/terraform terraform init -backend=false terraform validate - terraform plan - name: Setup Terraform lint if: ${{ matrix.java == '11' }} uses: terraform-linters/setup-tflint@a5a1af8c6551fb10c53f1cd4ba62359f1973746f # v3.1.1 diff --git a/examples/powertools-examples-core/terraform/main.tf b/examples/powertools-examples-core/terraform/main.tf index 67fb6b104..59cc5b022 100644 --- a/examples/powertools-examples-core/terraform/main.tf +++ b/examples/powertools-examples-core/terraform/main.tf @@ -1,3 +1,12 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} + # terraform modules module "powertools_for_java_lambda" { source = "./infra/" @@ -6,4 +15,9 @@ module "powertools_for_java_lambda" { output "api_url" { value = module.powertools_for_java_lambda.invoke description = "URL where the API gateway can be invoked" +} + +# Configure the AWS Provider +provider "aws" { + region = "us-east-1" } \ No newline at end of file diff --git a/examples/powertools-examples-core/terraform/pom.xml b/examples/powertools-examples-core/terraform/pom.xml index 5b4424278..1f0737918 100644 --- a/examples/powertools-examples-core/terraform/pom.xml +++ b/examples/powertools-examples-core/terraform/pom.xml @@ -129,6 +129,16 @@ true + + org.apache.maven.plugins + maven-surefire-plugin + 3.1.2 + + + handler + + + From 4b8336960c79844c6490c1f448d8a4e5deac36d6 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Mon, 16 Oct 2023 14:26:34 +0200 Subject: [PATCH 08/20] #1458 set aws credentials at the github actions level --- .github/workflows/pr_build.yml | 6 ++++++ examples/powertools-examples-core/terraform/main.tf | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 53346fa69..244f80eb2 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -71,6 +71,11 @@ jobs: - name: Setup Terraform if: ${{ matrix.java == '11' }} uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 #v2.0.3 + - name: Setup AWS credentials + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 + with: + role-to-assume: ${{ secrets.AWS_ROLE_ARN_TO_ASSUME }} + aws-region: ${{ env.AWS_REGION }} - name: Terraform validate if: ${{ matrix.java == '11' }} run: | @@ -78,6 +83,7 @@ jobs: cd examples/powertools-examples-core/terraform terraform init -backend=false terraform validate + terraform plan - name: Setup Terraform lint if: ${{ matrix.java == '11' }} uses: terraform-linters/setup-tflint@a5a1af8c6551fb10c53f1cd4ba62359f1973746f # v3.1.1 diff --git a/examples/powertools-examples-core/terraform/main.tf b/examples/powertools-examples-core/terraform/main.tf index 59cc5b022..10504088a 100644 --- a/examples/powertools-examples-core/terraform/main.tf +++ b/examples/powertools-examples-core/terraform/main.tf @@ -19,5 +19,4 @@ output "api_url" { # Configure the AWS Provider provider "aws" { - region = "us-east-1" } \ No newline at end of file From 2a63ecc867de7b01d23643db171bfb1c409013e2 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Fri, 6 Oct 2023 14:41:40 +0200 Subject: [PATCH 09/20] #1445 first implementation of terraform core example --- .gitignore | 5 +- examples/pom.xml | 1 + examples/powertools-examples-core/README.md | 1 + .../terraform/README.md | 27 +++ .../terraform/infra/api-gateway.tf | 92 ++++++++ .../terraform/infra/lambda.tf | 112 ++++++++++ .../terraform/infra/main.tf | 5 + .../terraform/infra/variables.tf | 14 ++ .../terraform/main.tf | 4 + .../terraform/pom.xml | 209 ++++++++++++++++++ .../src/main/java/helloworld/App.java | 105 +++++++++ .../src/main/java/helloworld/AppStream.java | 38 ++++ .../terraform/src/main/resources/log4j2.xml | 16 ++ .../src/test/java/helloworld/AppTest.java | 59 +++++ 14 files changed, 687 insertions(+), 1 deletion(-) create mode 100644 examples/powertools-examples-core/terraform/README.md create mode 100644 examples/powertools-examples-core/terraform/infra/api-gateway.tf create mode 100644 examples/powertools-examples-core/terraform/infra/lambda.tf create mode 100644 examples/powertools-examples-core/terraform/infra/main.tf create mode 100644 examples/powertools-examples-core/terraform/infra/variables.tf create mode 100644 examples/powertools-examples-core/terraform/main.tf create mode 100644 examples/powertools-examples-core/terraform/pom.xml create mode 100644 examples/powertools-examples-core/terraform/src/main/java/helloworld/App.java create mode 100644 examples/powertools-examples-core/terraform/src/main/java/helloworld/AppStream.java create mode 100644 examples/powertools-examples-core/terraform/src/main/resources/log4j2.xml create mode 100644 examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java diff --git a/.gitignore b/.gitignore index b404d2cb2..b965bf1aa 100644 --- a/.gitignore +++ b/.gitignore @@ -108,4 +108,7 @@ example/HelloWorldFunction/build /example/.gradle/ /example/.java-version .gradle -build/ \ No newline at end of file +build/ +.terraform +.terraform.lock.hcl +terraform.tfstate* \ No newline at end of file diff --git a/examples/pom.xml b/examples/pom.xml index 810ec1b36..900f095f8 100644 --- a/examples/pom.xml +++ b/examples/pom.xml @@ -33,6 +33,7 @@ powertools-examples-core/cdk/app powertools-examples-core/cdk/infra powertools-examples-core/serverless + powertools-examples-core/terraform powertools-examples-idempotency powertools-examples-parameters powertools-examples-serialization diff --git a/examples/powertools-examples-core/README.md b/examples/powertools-examples-core/README.md index 1d1dd031f..a0ffb125d 100644 --- a/examples/powertools-examples-core/README.md +++ b/examples/powertools-examples-core/README.md @@ -10,6 +10,7 @@ We provide examples for the following infrastructure-as-code tools: * [AWS SAM](sam/) * [AWS CDK](cdk/) * [Serverless framework](serverless/) +* [Terraform](terraform/) We also provide an example showing the integration of SAM, Powertools, and Gradle: diff --git a/examples/powertools-examples-core/terraform/README.md b/examples/powertools-examples-core/terraform/README.md new file mode 100644 index 000000000..ba03b8107 --- /dev/null +++ b/examples/powertools-examples-core/terraform/README.md @@ -0,0 +1,27 @@ +# Powertools for AWS Lambda (Java) - Core Utilities Example with Terraform + +This project demonstrates the Lambda for Powertools Java module deployed using [Terraform](https://www.terraform.io/). +For general information on the deployed example itself, you can refer to the parent [README](../README.md). +To install Terraform if you don't have it yet, you can follow the [Install Terraform Guide](https://developer.hashicorp.com/terraform/downloads?product_intent=terraform). + +## Configuration +Serverless Framework uses [serverless.yml](./serverless.yml) to define the application's AWS resources. +This file defines the Lambda function to be deployed as well as API Gateway for it. + +It is a [Maven](https://maven.apache.org/) based project, so you can open this project with any Maven compatible Java IDE to build and run tests. + + +## Deploy the sample application + +To deploy the app, simply run the following commands: +```bash +terraform init +terraform apply +``` + +## Useful commands + +To destroy the app +```bash +terraform destroy +``` diff --git a/examples/powertools-examples-core/terraform/infra/api-gateway.tf b/examples/powertools-examples-core/terraform/infra/api-gateway.tf new file mode 100644 index 000000000..d1ddd0275 --- /dev/null +++ b/examples/powertools-examples-core/terraform/infra/api-gateway.tf @@ -0,0 +1,92 @@ +resource "aws_api_gateway_rest_api" "hello_world_api" { + name = "hello_world_api" + description = "API Gateway endpoint URL for Prod stage for Hello World function" +} + +resource "aws_api_gateway_resource" "hello_resource" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + parent_id = "${aws_api_gateway_rest_api.hello_world_api.root_resource_id}" + path_part = "hello" +} + +resource "aws_api_gateway_resource" "hello_stream_resource" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + parent_id = "${aws_api_gateway_rest_api.hello_world_api.root_resource_id}" + path_part = "hellostream" +} + +resource "aws_api_gateway_method" "hello_get_method" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + resource_id = "${aws_api_gateway_resource.hello_resource.id}" + http_method = "GET" + authorization = "NONE" +} + +resource "aws_api_gateway_method" "hello_stream_get_method" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + resource_id = "${aws_api_gateway_resource.hello_stream_resource.id}" + http_method = "GET" + authorization = "NONE" +} + +resource "aws_api_gateway_integration" "java_lambda_integration" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + resource_id = "${aws_api_gateway_resource.hello_resource.id}" + http_method = "${aws_api_gateway_method.hello_get_method.http_method}" + + integration_http_method = "POST" + type = "AWS_PROXY" + uri = "${aws_lambda_function.hello_world_lambda.invoke_arn}" +} + +resource "aws_api_gateway_integration" "java_stream_lambda_integration" { + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + resource_id = "${aws_api_gateway_resource.hello_stream_resource.id}" + http_method = "${aws_api_gateway_method.hello_stream_get_method.http_method}" + + integration_http_method = "POST" + type = "AWS_PROXY" + uri = "${aws_lambda_function.hello_world_stream_lambda.invoke_arn}" +} + +resource "aws_api_gateway_deployment" "prod_deployment" { + depends_on = [aws_api_gateway_integration.java_lambda_integration, aws_api_gateway_integration.java_stream_lambda_integration] + rest_api_id = "${aws_api_gateway_rest_api.hello_world_api.id}" + stage_name = "prod" +} + +# Allows API gateway to invoke lambda +resource "aws_lambda_permission" "hello_world_lambda_invoke" { + statement_id = "AllowAPIGatewayInvoke" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.hello_world_lambda.function_name}" + principal = "apigateway.amazonaws.com" + source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/${aws_api_gateway_deployment.prod_deployment.stage_name}/GET/hello" +} + +# Allows API gateway to invoke lambda +resource "aws_lambda_permission" "hello_world_lambda_testinvoke" { + statement_id = "AllowAPIGatewayTestInvoke" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.hello_world_lambda.function_name}" + principal = "apigateway.amazonaws.com" + source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/test-invoke-stage/GET/hello" +} + +# Allows API gateway to invoke lambda +resource "aws_lambda_permission" "hello_world_stream_lambda_invoke" { + statement_id = "AllowAPIGatewayInvoke" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.hello_world_stream_lambda.function_name}" + principal = "apigateway.amazonaws.com" + source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/${aws_api_gateway_deployment.prod_deployment.stage_name}/GET/hellostream" +} + +# Allows API gateway to invoke lambda +resource "aws_lambda_permission" "hello_world_stream_lambda_testinvoke" { + statement_id = "AllowAPIGatewayTestInvoke" + action = "lambda:InvokeFunction" + function_name = "${aws_lambda_function.hello_world_stream_lambda.function_name}" + principal = "apigateway.amazonaws.com" + source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/test-invoke-stage/GET/hellostream" +} diff --git a/examples/powertools-examples-core/terraform/infra/lambda.tf b/examples/powertools-examples-core/terraform/infra/lambda.tf new file mode 100644 index 000000000..67c74184f --- /dev/null +++ b/examples/powertools-examples-core/terraform/infra/lambda.tf @@ -0,0 +1,112 @@ +resource "aws_lambda_function" "hello_world_lambda" { + runtime = "java11" + filename = "target/helloworld-lambda.jar" + source_code_hash = filebase64sha256("target/helloworld-lambda.jar") + function_name = "hello_world_lambda" + + handler = "helloworld.App" + description = "Powertools example, deployed by Terraform" + timeout = 20 + memory_size = 512 + role = "${aws_iam_role.iam_role_for_lambda.arn}" + environment { + variables = { + POWERTOOLS_LOG_LEVEL = "INFO" + POWERTOOLS_LOGGER_SAMPLE_RATE = "0.1" + POWERTOOLS_LOGGER_LOG_EVENT = "true" + POWERTOOLS_METRICS_NAMESPACE = "Coreutilities" + } + } + tracing_config { + mode = "Active" + } + depends_on = [aws_cloudwatch_log_group.log_group] +} + +resource "aws_lambda_function" "hello_world_stream_lambda" { + runtime = "java11" + filename = "target/helloworld-lambda.jar" + source_code_hash = filebase64sha256("target/helloworld-lambda.jar") + function_name = "hello_world_stream_lambda" + + handler = "helloworld.AppStream" + description = "Powertools example, deployed by Terraform" + timeout = 20 + memory_size = 512 + role = "${aws_iam_role.iam_role_for_lambda.arn}" + environment { + variables = { + POWERTOOLS_LOG_LEVEL = "INFO" + POWERTOOLS_LOGGER_SAMPLE_RATE = "0.7" + POWERTOOLS_LOGGER_LOG_EVENT = "true" + POWERTOOLS_METRICS_NAMESPACE = "Coreutilities" + POWERTOOLS_SERVICE_NAME = "hello" + } + } + tracing_config { + mode = "Active" + } + depends_on = [aws_cloudwatch_log_group.log_group] +} + +# Create a log group for the lambda +resource "aws_cloudwatch_log_group" "log_group" { + name = "/aws/lambda/hello_world_lambda" +} + +# Create a log group for the lambda +resource "aws_cloudwatch_log_group" "log_group_stream" { + name = "/aws/lambda/hello_world_stream_lambda" +} + +# lambda role +resource "aws_iam_role" "iam_role_for_lambda" { + name = "lambda-invoke-role" + assume_role_policy = < + 4.0.0 + + software.amazon.lambda.examples + 1.18.0-SNAPSHOT + powertools-examples-core-terraform + jar + + Powertools for AWS Lambda (Java) library Examples - Core + + + 2.20.0 + 1.8 + 1.8 + + + + + software.amazon.lambda + powertools-tracing + ${project.version} + + + software.amazon.lambda + powertools-logging + ${project.version} + + + software.amazon.lambda + powertools-metrics + ${project.version} + + + com.amazonaws + aws-lambda-java-core + 1.2.2 + + + com.amazonaws + aws-lambda-java-events + 3.11.2 + + + org.apache.logging.log4j + log4j-core + ${log4j.version} + + + org.apache.logging.log4j + log4j-api + ${log4j.version} + + + + junit + junit + 4.13.2 + test + + + + + helloworld-lambda + + + dev.aspectj + aspectj-maven-plugin + 1.13.1 + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-tracing + + + software.amazon.lambda + powertools-logging + + + software.amazon.lambda + powertools-metrics + + + + + + + compile + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.0 + + + package + + shade + + + + + + + + + + + + com.github.edwgiz + maven-shade-plugin.log4j2-cachefile-transformer + 2.15 + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + + + + + jdk8 + + (,11) + + + 1.9.7 + + + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + + + dev.aspectj + aspectj-maven-plugin + ${aspectj.plugin.version} + + ${maven.compiler.source} + ${maven.compiler.target} + ${maven.compiler.target} + + + software.amazon.lambda + powertools-tracing + + + software.amazon.lambda + powertools-logging + + + software.amazon.lambda + powertools-metrics + + + + + + + compile + test-compile + + + + + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + + + + diff --git a/examples/powertools-examples-core/terraform/src/main/java/helloworld/App.java b/examples/powertools-examples-core/terraform/src/main/java/helloworld/App.java new file mode 100644 index 000000000..dacd7f1d4 --- /dev/null +++ b/examples/powertools-examples-core/terraform/src/main/java/helloworld/App.java @@ -0,0 +1,105 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. + * Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package helloworld; + +import static software.amazon.lambda.powertools.metrics.MetricsUtils.metricsLogger; +import static software.amazon.lambda.powertools.metrics.MetricsUtils.withSingleMetric; +import static software.amazon.lambda.powertools.tracing.TracingUtils.putMetadata; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent; +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import software.amazon.cloudwatchlogs.emf.model.DimensionSet; +import software.amazon.cloudwatchlogs.emf.model.Unit; +import software.amazon.lambda.powertools.logging.Logging; +import software.amazon.lambda.powertools.logging.LoggingUtils; +import software.amazon.lambda.powertools.metrics.Metrics; +import software.amazon.lambda.powertools.tracing.CaptureMode; +import software.amazon.lambda.powertools.tracing.Tracing; +import software.amazon.lambda.powertools.tracing.TracingUtils; + +/** + * Handler for requests to Lambda function. + */ +public class App implements RequestHandler { + private final static Logger log = LogManager.getLogger(App.class); + + // This is controlled by POWERTOOLS_LOGGER_SAMPLE_RATE environment variable + // @Logging(logEvent = true, samplingRate = 0.7) + // This is controlled by POWERTOOLS_METRICS_NAMESPACE environment variable + // @Metrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true) + // This is controlled by POWERTOOLS_TRACER_CAPTURE_ERROR environment variable + @Tracing(captureMode = CaptureMode.RESPONSE_AND_ERROR) + public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEvent input, final Context context) { + Map headers = new HashMap<>(); + + headers.put("Content-Type", "application/json"); + headers.put("X-Custom-Header", "application/json"); + + metricsLogger().putMetric("CustomMetric1", 1, Unit.COUNT); + + withSingleMetric("CustomMetrics2", 1, Unit.COUNT, "Another", (metric) -> + { + metric.setDimensions(DimensionSet.of("AnotherService", "CustomService")); + metric.setDimensions(DimensionSet.of("AnotherService1", "CustomService1")); + }); + + LoggingUtils.appendKey("test", "willBeLogged"); + + APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent() + .withHeaders(headers); + try { + final String pageContents = this.getPageContents("https://checkip.amazonaws.com"); + log.info(pageContents); + TracingUtils.putAnnotation("Test", "New"); + String output = String.format("{ \"message\": \"hello world\", \"location\": \"%s\" }", pageContents); + + TracingUtils.withSubsegment("loggingResponse", subsegment -> + { + String sampled = "log something out"; + log.info(sampled); + log.info(output); + }); + + log.info("After output"); + return response + .withStatusCode(200) + .withBody(output); + } catch (RuntimeException | IOException e) { + return response + .withBody("{}") + .withStatusCode(500); + } + } + + @Tracing(namespace = "getPageContents", captureMode = CaptureMode.DISABLED) + private String getPageContents(String address) throws IOException { + URL url = new URL(address); + putMetadata("getPageContents", address); + try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()))) { + return br.lines().collect(Collectors.joining(System.lineSeparator())); + } + } +} diff --git a/examples/powertools-examples-core/terraform/src/main/java/helloworld/AppStream.java b/examples/powertools-examples-core/terraform/src/main/java/helloworld/AppStream.java new file mode 100644 index 000000000..401ef8c48 --- /dev/null +++ b/examples/powertools-examples-core/terraform/src/main/java/helloworld/AppStream.java @@ -0,0 +1,38 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. + * Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package helloworld; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestStreamHandler; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; +import software.amazon.lambda.powertools.logging.Logging; +import software.amazon.lambda.powertools.metrics.Metrics; + +public class AppStream implements RequestStreamHandler { + private static final ObjectMapper mapper = new ObjectMapper(); + + @Override + @Logging(logEvent = true) + @Metrics(namespace = "ServerlessAirline", service = "payment", captureColdStart = true) + public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException { + Map map = mapper.readValue(input, Map.class); + + System.out.println(map.size()); + } +} diff --git a/examples/powertools-examples-core/terraform/src/main/resources/log4j2.xml b/examples/powertools-examples-core/terraform/src/main/resources/log4j2.xml new file mode 100644 index 000000000..0cc0953f0 --- /dev/null +++ b/examples/powertools-examples-core/terraform/src/main/resources/log4j2.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java new file mode 100644 index 000000000..70dad8d71 --- /dev/null +++ b/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2023 Amazon.com, Inc. or its affiliates. + * Licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package helloworld; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; +import com.amazonaws.xray.AWSXRay; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class AppTest { + + @Before + public void setup() { + if (null == System.getenv("LAMBDA_TASK_ROOT")) { + AWSXRay.beginSegment("test"); + } + } + + @After + public void tearDown() { + if (AWSXRay.getCurrentSubsegmentOptional().isPresent()) { + AWSXRay.endSubsegment(); + } + + if (null == System.getenv("LAMBDA_TASK_ROOT")) { + AWSXRay.endSegment(); + } + } + + @Test + public void successfulResponse() { + App app = new App(); + APIGatewayProxyResponseEvent result = app.handleRequest(null, null); + assertEquals(result.getStatusCode().intValue(), 200); + assertEquals(result.getHeaders().get("Content-Type"), "application/json"); + String content = result.getBody(); + assertNotNull(content); + assertTrue(content.contains("\"message\"")); + assertTrue(content.contains("\"hello world\"")); + assertTrue(content.contains("\"location\"")); + } +} From b2e6f4699a1869903681e8b23a3f48d9af8965f2 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Fri, 6 Oct 2023 14:54:28 +0200 Subject: [PATCH 10/20] #1445 updated readme to include maven instructions --- .gitignore | 3 +-- examples/powertools-examples-core/terraform/README.md | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index b965bf1aa..6615ac729 100644 --- a/.gitignore +++ b/.gitignore @@ -109,6 +109,5 @@ example/HelloWorldFunction/build /example/.java-version .gradle build/ -.terraform -.terraform.lock.hcl +.terraform* terraform.tfstate* \ No newline at end of file diff --git a/examples/powertools-examples-core/terraform/README.md b/examples/powertools-examples-core/terraform/README.md index ba03b8107..27d47fbbb 100644 --- a/examples/powertools-examples-core/terraform/README.md +++ b/examples/powertools-examples-core/terraform/README.md @@ -16,7 +16,7 @@ It is a [Maven](https://maven.apache.org/) based project, so you can open this p To deploy the app, simply run the following commands: ```bash terraform init -terraform apply +mvn package && terraform apply ``` ## Useful commands From b843ede589e3146de5c5938377c61df37c216a94 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Fri, 13 Oct 2023 10:03:19 +0200 Subject: [PATCH 11/20] #1458 fixed readme typo + removed lambda env configuration + output api URL --- .../terraform/README.md | 2 +- .../terraform/infra/api-gateway.tf | 2 ++ .../terraform/infra/lambda.tf | 17 ----------------- .../powertools-examples-core/terraform/main.tf | 5 +++++ 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/examples/powertools-examples-core/terraform/README.md b/examples/powertools-examples-core/terraform/README.md index 27d47fbbb..71c78d437 100644 --- a/examples/powertools-examples-core/terraform/README.md +++ b/examples/powertools-examples-core/terraform/README.md @@ -5,7 +5,7 @@ For general information on the deployed example itself, you can refer to the par To install Terraform if you don't have it yet, you can follow the [Install Terraform Guide](https://developer.hashicorp.com/terraform/downloads?product_intent=terraform). ## Configuration -Serverless Framework uses [serverless.yml](./serverless.yml) to define the application's AWS resources. +Terraform uses [main.tf](./main.tf) to define the application's AWS resources. This file defines the Lambda function to be deployed as well as API Gateway for it. It is a [Maven](https://maven.apache.org/) based project, so you can open this project with any Maven compatible Java IDE to build and run tests. diff --git a/examples/powertools-examples-core/terraform/infra/api-gateway.tf b/examples/powertools-examples-core/terraform/infra/api-gateway.tf index d1ddd0275..dba1c3616 100644 --- a/examples/powertools-examples-core/terraform/infra/api-gateway.tf +++ b/examples/powertools-examples-core/terraform/infra/api-gateway.tf @@ -90,3 +90,5 @@ resource "aws_lambda_permission" "hello_world_stream_lambda_testinvoke" { principal = "apigateway.amazonaws.com" source_arn = "${aws_api_gateway_rest_api.hello_world_api.execution_arn}/test-invoke-stage/GET/hellostream" } + +output "invoke" {value=aws_api_gateway_deployment.prod_deployment.invoke_url} \ No newline at end of file diff --git a/examples/powertools-examples-core/terraform/infra/lambda.tf b/examples/powertools-examples-core/terraform/infra/lambda.tf index 67c74184f..abebccf54 100644 --- a/examples/powertools-examples-core/terraform/infra/lambda.tf +++ b/examples/powertools-examples-core/terraform/infra/lambda.tf @@ -9,14 +9,6 @@ resource "aws_lambda_function" "hello_world_lambda" { timeout = 20 memory_size = 512 role = "${aws_iam_role.iam_role_for_lambda.arn}" - environment { - variables = { - POWERTOOLS_LOG_LEVEL = "INFO" - POWERTOOLS_LOGGER_SAMPLE_RATE = "0.1" - POWERTOOLS_LOGGER_LOG_EVENT = "true" - POWERTOOLS_METRICS_NAMESPACE = "Coreutilities" - } - } tracing_config { mode = "Active" } @@ -34,15 +26,6 @@ resource "aws_lambda_function" "hello_world_stream_lambda" { timeout = 20 memory_size = 512 role = "${aws_iam_role.iam_role_for_lambda.arn}" - environment { - variables = { - POWERTOOLS_LOG_LEVEL = "INFO" - POWERTOOLS_LOGGER_SAMPLE_RATE = "0.7" - POWERTOOLS_LOGGER_LOG_EVENT = "true" - POWERTOOLS_METRICS_NAMESPACE = "Coreutilities" - POWERTOOLS_SERVICE_NAME = "hello" - } - } tracing_config { mode = "Active" } diff --git a/examples/powertools-examples-core/terraform/main.tf b/examples/powertools-examples-core/terraform/main.tf index c672bc769..67fb6b104 100644 --- a/examples/powertools-examples-core/terraform/main.tf +++ b/examples/powertools-examples-core/terraform/main.tf @@ -2,3 +2,8 @@ module "powertools_for_java_lambda" { source = "./infra/" } + +output "api_url" { + value = module.powertools_for_java_lambda.invoke + description = "URL where the API gateway can be invoked" +} \ No newline at end of file From f7a9747479227ba3c18b858a32a0175d02c50d37 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Fri, 13 Oct 2023 16:29:41 +0200 Subject: [PATCH 12/20] #1458 added tflint and tf validate to the PR build --- .github/workflows/pr_build.yml | 20 +++++++++++++++++++ .../terraform/.tflint.hcl | 3 +++ 2 files changed, 23 insertions(+) create mode 100644 examples/powertools-examples-core/terraform/.tflint.hcl diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 73ae67553..fec25276b 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -68,6 +68,26 @@ jobs: run: | cd examples/powertools-examples-core/gradle ./gradlew build + - name: Setup Terraform + if: ${{ matrix.java == '11' }} + uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 #v2.0.3 + - name: Terraform validate + if: ${{ matrix.java == '11' }} + run: | + terraform -version + cd examples/powertools-examples-core/terraform + terraform init + terraform validate + - name: Setup Terraform lint + if: ${{ matrix.java == '11' }} + uses: terraform-linters/setup-tflint@a5a1af8c6551fb10c53f1cd4ba62359f1973746f # v3.1.1 + - name: Terraform lint + if: ${{ matrix.java == '11' }} + run: | + tflint --version + cd examples/powertools-examples-core/terraform + tflint --init + tflint -f compact - name: Upload coverage to Codecov uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 # v3.1.1 if: ${{ matrix.java == '11' }} # publish results once diff --git a/examples/powertools-examples-core/terraform/.tflint.hcl b/examples/powertools-examples-core/terraform/.tflint.hcl new file mode 100644 index 000000000..18e69352b --- /dev/null +++ b/examples/powertools-examples-core/terraform/.tflint.hcl @@ -0,0 +1,3 @@ +rule "terraform_required_version" { + enabled = false +} \ No newline at end of file From 53691a9815a1c75b6e37751c899630c58137982e Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Fri, 13 Oct 2023 17:13:00 +0200 Subject: [PATCH 13/20] #1458 tf plan, removed tf aws variables, removed xray from AppTest --- .github/workflows/pr_build.yml | 1 + .../terraform/infra/main.tf | 5 ----- .../terraform/infra/variables.tf | 14 ------------- .../src/test/java/helloworld/AppTest.java | 21 ------------------- 4 files changed, 1 insertion(+), 40 deletions(-) delete mode 100644 examples/powertools-examples-core/terraform/infra/main.tf delete mode 100644 examples/powertools-examples-core/terraform/infra/variables.tf diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index fec25276b..76a7620fe 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -78,6 +78,7 @@ jobs: cd examples/powertools-examples-core/terraform terraform init terraform validate + terraform plan - name: Setup Terraform lint if: ${{ matrix.java == '11' }} uses: terraform-linters/setup-tflint@a5a1af8c6551fb10c53f1cd4ba62359f1973746f # v3.1.1 diff --git a/examples/powertools-examples-core/terraform/infra/main.tf b/examples/powertools-examples-core/terraform/infra/main.tf deleted file mode 100644 index 4fc5d91b1..000000000 --- a/examples/powertools-examples-core/terraform/infra/main.tf +++ /dev/null @@ -1,5 +0,0 @@ -provider "aws" { - access_key = "${var.aws_access_key}" - secret_key = "${var.aws_secret_key}" - region = "${var.region}" -} diff --git a/examples/powertools-examples-core/terraform/infra/variables.tf b/examples/powertools-examples-core/terraform/infra/variables.tf deleted file mode 100644 index f069c7b95..000000000 --- a/examples/powertools-examples-core/terraform/infra/variables.tf +++ /dev/null @@ -1,14 +0,0 @@ -variable "aws_access_key" { - # set aws access key - default = "" -} - -variable "aws_secret_key" { - # set aws secret key - default = "" -} - -variable "region" { - # set aws region - default = "" -} \ No newline at end of file diff --git a/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java b/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java index 70dad8d71..0ca4f264d 100644 --- a/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java +++ b/examples/powertools-examples-core/terraform/src/test/java/helloworld/AppTest.java @@ -19,31 +19,10 @@ import static org.junit.Assert.assertTrue; import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent; -import com.amazonaws.xray.AWSXRay; -import org.junit.After; -import org.junit.Before; import org.junit.Test; public class AppTest { - @Before - public void setup() { - if (null == System.getenv("LAMBDA_TASK_ROOT")) { - AWSXRay.beginSegment("test"); - } - } - - @After - public void tearDown() { - if (AWSXRay.getCurrentSubsegmentOptional().isPresent()) { - AWSXRay.endSubsegment(); - } - - if (null == System.getenv("LAMBDA_TASK_ROOT")) { - AWSXRay.endSegment(); - } - } - @Test public void successfulResponse() { App app = new App(); From f85f5e5c26624f73bda538e94e6d34a047a3aebe Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Fri, 13 Oct 2023 17:22:29 +0200 Subject: [PATCH 14/20] #1458 tentative fix -> tf validate fails without proper AWS credentials --- .github/workflows/pr_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 76a7620fe..c9a1a6e23 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -76,7 +76,7 @@ jobs: run: | terraform -version cd examples/powertools-examples-core/terraform - terraform init + terraform init -backend=false terraform validate terraform plan - name: Setup Terraform lint From 86155a9bdac8469f6383326c8416c26c1b883525 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Mon, 16 Oct 2023 13:40:13 +0200 Subject: [PATCH 15/20] #1458 add LAMBDA_TASK_ROOT at pom level, removed tf plan for now, changed tf providers to pass tf validate --- .github/workflows/pr_build.yml | 1 - .../powertools-examples-core/terraform/main.tf | 14 ++++++++++++++ .../powertools-examples-core/terraform/pom.xml | 10 ++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index c9a1a6e23..53346fa69 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -78,7 +78,6 @@ jobs: cd examples/powertools-examples-core/terraform terraform init -backend=false terraform validate - terraform plan - name: Setup Terraform lint if: ${{ matrix.java == '11' }} uses: terraform-linters/setup-tflint@a5a1af8c6551fb10c53f1cd4ba62359f1973746f # v3.1.1 diff --git a/examples/powertools-examples-core/terraform/main.tf b/examples/powertools-examples-core/terraform/main.tf index 67fb6b104..59cc5b022 100644 --- a/examples/powertools-examples-core/terraform/main.tf +++ b/examples/powertools-examples-core/terraform/main.tf @@ -1,3 +1,12 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} + # terraform modules module "powertools_for_java_lambda" { source = "./infra/" @@ -6,4 +15,9 @@ module "powertools_for_java_lambda" { output "api_url" { value = module.powertools_for_java_lambda.invoke description = "URL where the API gateway can be invoked" +} + +# Configure the AWS Provider +provider "aws" { + region = "us-east-1" } \ No newline at end of file diff --git a/examples/powertools-examples-core/terraform/pom.xml b/examples/powertools-examples-core/terraform/pom.xml index 5b4424278..1f0737918 100644 --- a/examples/powertools-examples-core/terraform/pom.xml +++ b/examples/powertools-examples-core/terraform/pom.xml @@ -129,6 +129,16 @@ true + + org.apache.maven.plugins + maven-surefire-plugin + 3.1.2 + + + handler + + + From 01bbf80b5f4c0dbbf320f6688f25cade1e8d9374 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Mon, 16 Oct 2023 14:26:34 +0200 Subject: [PATCH 16/20] #1458 set aws credentials at the github actions level --- .github/workflows/pr_build.yml | 6 ++++++ examples/powertools-examples-core/terraform/main.tf | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 53346fa69..244f80eb2 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -71,6 +71,11 @@ jobs: - name: Setup Terraform if: ${{ matrix.java == '11' }} uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 #v2.0.3 + - name: Setup AWS credentials + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 + with: + role-to-assume: ${{ secrets.AWS_ROLE_ARN_TO_ASSUME }} + aws-region: ${{ env.AWS_REGION }} - name: Terraform validate if: ${{ matrix.java == '11' }} run: | @@ -78,6 +83,7 @@ jobs: cd examples/powertools-examples-core/terraform terraform init -backend=false terraform validate + terraform plan - name: Setup Terraform lint if: ${{ matrix.java == '11' }} uses: terraform-linters/setup-tflint@a5a1af8c6551fb10c53f1cd4ba62359f1973746f # v3.1.1 diff --git a/examples/powertools-examples-core/terraform/main.tf b/examples/powertools-examples-core/terraform/main.tf index 59cc5b022..10504088a 100644 --- a/examples/powertools-examples-core/terraform/main.tf +++ b/examples/powertools-examples-core/terraform/main.tf @@ -19,5 +19,4 @@ output "api_url" { # Configure the AWS Provider provider "aws" { - region = "us-east-1" } \ No newline at end of file From 3f5e20a09e70579844b53beebb40565a7d1bb0d2 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Tue, 17 Oct 2023 09:42:34 +0200 Subject: [PATCH 17/20] #1458 revert to having a simple aws provider configuration --- .github/workflows/pr_build.yml | 5 ----- examples/powertools-examples-core/terraform/main.tf | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index 244f80eb2..c9a1a6e23 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -71,11 +71,6 @@ jobs: - name: Setup Terraform if: ${{ matrix.java == '11' }} uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 #v2.0.3 - - name: Setup AWS credentials - uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 - with: - role-to-assume: ${{ secrets.AWS_ROLE_ARN_TO_ASSUME }} - aws-region: ${{ env.AWS_REGION }} - name: Terraform validate if: ${{ matrix.java == '11' }} run: | diff --git a/examples/powertools-examples-core/terraform/main.tf b/examples/powertools-examples-core/terraform/main.tf index 10504088a..59cc5b022 100644 --- a/examples/powertools-examples-core/terraform/main.tf +++ b/examples/powertools-examples-core/terraform/main.tf @@ -19,4 +19,5 @@ output "api_url" { # Configure the AWS Provider provider "aws" { + region = "us-east-1" } \ No newline at end of file From d94426422c08eec4ae252f5d975cd03e46cbfc52 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Wed, 18 Oct 2023 09:19:53 +0200 Subject: [PATCH 18/20] #1458 changed transformer --- examples/powertools-examples-core/terraform/pom.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/powertools-examples-core/terraform/pom.xml b/examples/powertools-examples-core/terraform/pom.xml index 1f0737918..12e50bc47 100644 --- a/examples/powertools-examples-core/terraform/pom.xml +++ b/examples/powertools-examples-core/terraform/pom.xml @@ -106,9 +106,7 @@ - - + From 01e1388ca66108e77b1dd51ebe4e857fa25ff361 Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Wed, 18 Oct 2023 16:27:48 +0200 Subject: [PATCH 19/20] #1458 fixed shade plugin transformer dependency --- examples/powertools-examples-core/terraform/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/powertools-examples-core/terraform/pom.xml b/examples/powertools-examples-core/terraform/pom.xml index 12e50bc47..8da2780d8 100644 --- a/examples/powertools-examples-core/terraform/pom.xml +++ b/examples/powertools-examples-core/terraform/pom.xml @@ -113,9 +113,9 @@ - com.github.edwgiz - maven-shade-plugin.log4j2-cachefile-transformer - 2.15 + org.apache.logging.log4j + log4j-transform-maven-shade-plugin-extensions + 0.1.0 From 5648cb03043eea23864f607ff36bf867a2b1e4fc Mon Sep 17 00:00:00 2001 From: Pascal Romanens Date: Thu, 19 Oct 2023 11:26:13 +0200 Subject: [PATCH 20/20] #1458 enabled aws credentials in github action --- .github/workflows/pr_build.yml | 8 ++++++++ examples/powertools-examples-core/terraform/main.tf | 1 - 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr_build.yml b/.github/workflows/pr_build.yml index c9a1a6e23..79945f237 100644 --- a/.github/workflows/pr_build.yml +++ b/.github/workflows/pr_build.yml @@ -53,6 +53,9 @@ jobs: env: JAVA: ${{ matrix.java }} AWS_REGION: eu-west-1 + permissions: + id-token: write # needed to interact with GitHub's OIDC Token endpoint. + contents: read steps: - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Setup java @@ -71,6 +74,11 @@ jobs: - name: Setup Terraform if: ${{ matrix.java == '11' }} uses: hashicorp/setup-terraform@633666f66e0061ca3b725c73b2ec20cd13a8fdd1 #v2.0.3 + - name: Setup AWS credentials + uses: aws-actions/configure-aws-credentials@5fd3084fc36e372ff1fff382a39b10d03659f355 # v2.2.0 + with: + role-to-assume: ${{ secrets.AWS_ROLE_ARN_TO_ASSUME }} + aws-region: ${{ env.AWS_REGION }} - name: Terraform validate if: ${{ matrix.java == '11' }} run: | diff --git a/examples/powertools-examples-core/terraform/main.tf b/examples/powertools-examples-core/terraform/main.tf index 59cc5b022..10504088a 100644 --- a/examples/powertools-examples-core/terraform/main.tf +++ b/examples/powertools-examples-core/terraform/main.tf @@ -19,5 +19,4 @@ output "api_url" { # Configure the AWS Provider provider "aws" { - region = "us-east-1" } \ No newline at end of file