-
Notifications
You must be signed in to change notification settings - Fork 90
feat: Terraform example #1458
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Terraform example #1458
Changes from all commits
0a25912
1745a6b
f8d721a
f6f13a6
ccee404
5ba42cd
1458293
e1e9d18
df3101d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
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. | ||
|
||
|
||
## Deploy the sample application | ||
|
||
To deploy the app, simply run the following commands: | ||
```bash | ||
terraform init | ||
mvn package && terraform apply | ||
``` | ||
|
||
## Useful commands | ||
|
||
To destroy the app | ||
```bash | ||
terraform destroy | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
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" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here? |
||
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" | ||
} | ||
|
||
output "invoke" {value=aws_api_gateway_deployment.prod_deployment.invoke_url} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
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}" | ||
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}" | ||
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 = <<EOF | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Action": "sts:AssumeRole", | ||
"Principal": { | ||
"Service": "lambda.amazonaws.com" | ||
}, | ||
"Effect": "Allow", | ||
"Sid": "" | ||
} | ||
] | ||
} | ||
EOF | ||
} | ||
|
||
# lambda policy, allow logs to be published to CloudWatch, and traces to Xray | ||
resource "aws_iam_policy" "iam_policy_for_lambda" { | ||
name = "lambda-invoke-policy" | ||
path = "/" | ||
|
||
policy = <<EOF | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Sid": "LambdaPolicy", | ||
"Effect": "Allow", | ||
"Action": [ | ||
"logs:CreateLogGroup", | ||
"logs:CreateLogStream", | ||
"logs:PutLogEvents", | ||
"xray:PutTelemetryRecords", | ||
"xray:PutTraceSegments" | ||
], | ||
"Resource": "*" | ||
} | ||
] | ||
} | ||
EOF | ||
} | ||
|
||
# Attach the policy to the role | ||
resource "aws_iam_role_policy_attachment" "aws_iam_role_policy_attachment" { | ||
role = "${aws_iam_role.iam_role_for_lambda.name}" | ||
policy_arn = "${aws_iam_policy.iam_policy_for_lambda.arn}" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
provider "aws" { | ||
access_key = "${var.aws_access_key}" | ||
secret_key = "${var.aws_secret_key}" | ||
region = "${var.region}" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
variable "aws_access_key" { | ||
# set aws access key | ||
default = "" | ||
} | ||
|
||
variable "aws_secret_key" { | ||
# set aws secret key | ||
default = "" | ||
} | ||
|
||
variable "region" { | ||
# set aws region | ||
default = "" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# terraform modules | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How do we know that we haven't broken this - can we lint it as part of the build? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could we do a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there is also this: https://github.com/terraform-linters/setup-tflint. Should we add it? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @scottgerring we should something similar for SAM and the others... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok I will add some form of linting/validation |
||
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" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this test-invoke-stage ?
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Required stage to test the lambda invocation from the API Gateway console. Can be removed, but CDK example deploys similar permissions, including that test-invoke-stage.
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/apigateway/test-invoke-method.html