Skip to content

Commit cadc1ce

Browse files
author
Archana Venkitaramanan
committed
made changes
1 parent b15bf9c commit cadc1ce

File tree

2 files changed

+71
-33
lines changed

2 files changed

+71
-33
lines changed

apigw-lambda-rekognition/README.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Content safety with Image Moderation using AWS API Gateway and AWS Lambda
1+
# Content safety with Image Moderation using Amazon API Gateway and AWS Lambda
22

3-
Using this sample pattern, users can access AWS API Gateway to generate a pre-signed URL through an AWS Lambda function, using which they can upload images to an Amazon S3 bucket. This URL allows secure and temporary access for uploading files directly to S3.
3+
Using this sample pattern, users can securely upload images to an Amazon S3 bucket by requesting a pre-signed URL through Amazon API Gateway. This URL allows secure and temporary access for uploading files directly to S3.
44

5-
Once an image is uploaded, an S3 event triggers another Lambda function that uses the DetectModerationLabels API to analyze the content. If the image is identified as inappropriate, a notification is sent via Amazon SNS, ensuring automated content moderation and alerting.
5+
Once an image is uploaded, an S3 event invokes another Lambda function to analyze the content using the DetectModerationLabels API. If the image is identified as inappropriate, a notification is sent via Amazon SNS, ensuring automated content moderation and alerting.
66

77
Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/apigw-lambda-rekognition
88

@@ -49,25 +49,27 @@ Important: this application uses various AWS services and there are costs associ
4949
5050
curl --location 'https://<api-id>.execute-api.<region>.amazonaws.com/dev/generate-presigned-url' --header 'Content-Type: text/plain' --data '{"object_name": "image.png", "content_type": "image/png"}'
5151
52-
Note: Replace 'api-id' with the generated API ID from Terraform, 'region' with the region where the API is deployed, 'object_name' with your desired name for the S3 object and 'content_type' with the content type of the image, for ex, png or jpeg
52+
Note: Replace 'api-id' with the generated API ID from Terraform, 'region' with the region where the API is deployed (refer to the Terraform Outputs section) 'object_name' with your desired name for the S3 object and 'content_type' with the content type of the image, for ex, png or jpeg
5353
5454
1. Get the pre-signed URL from the previous step and use the following cURL command to upload the object in S3:
5555
56-
curl --location --request PUT '<presigned-url>' --header 'Content-Type: image/png' --data '<path-of-the-object>.png'
56+
curl -v --location --request PUT '<presigned-url>' --header 'Content-Type: image/png' --data '<path-of-the-object>.png'
5757
5858
Note: Replace 'presigned-url' with pre-signed URL generated in the previous step. 'Content-Type' should match the content type used to generate the pre-signed URL in the previous step. Make sure you are passing the correct path of the object in the --data parameter.
5959
60-
1. Once the object is uploaded successfully, the Lambda function will be invoked and if the image is inappropirate, a message is sent to the SNS Topic, which is then received by the subscriber.
60+
Once this command is run successfully and the object is uploaded, HTTP 200 OK should be seen. You can also check the S3 bucket to see if the object is uploaded correctly.
61+
62+
1. Once the object is uploaded successfully, the "process_s3-event" Lambda function is invoked and if the image is inappropriate, a message is sent to the SNS topic, which is then received by the subscriber.
6163
6264
## Cleanup
6365
6466
1. Delete the SNS Subscription:
65-
Go to SNS > Subsciptions > Select your Subscription and click on Delete
67+
Go to SNS > Subsciptions > Select your Subscription and choose Delete
6668
6769
https://docs.aws.amazon.com/sns/latest/dg/sns-delete-subscription-topic.html
6870
6971
1. Delete all the objects from S3:
70-
Go to S3 > Select all the objects > Click on Delete
72+
Go to S3 > Select all objects > choose Delete
7173
7274
https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-objects.html
7375
https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-multiple-objects.html
@@ -92,6 +94,6 @@ Important: this application uses various AWS services and there are costs associ
9294
terraform show
9395
```
9496
----
95-
Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
97+
Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
9698
9799
SPDX-License-Identifier: MIT-0

apigw-lambda-rekognition/main.tf

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
variable "region" {}
2-
32
provider "aws" {
4-
region = "${var.region}"
3+
region = var.region
54
}
65
variable "prefix" {
7-
description = "Prefix for S3 bucket name"
6+
description = "Prefix to associate with the resources"
87
type = string
98
}
109
resource "aws_s3_bucket" "upload_bucket" {
1110
bucket = "${lower(var.prefix)}-s3-upload"
1211
}
1312
resource "aws_sns_topic" "sns_topic" {
14-
name = "SNS-Topic"
13+
name = "${lower(var.prefix)}-sns-topic"
1514
}
1615
resource "aws_iam_role" "lambda_role" {
17-
name = "${lower(var.prefix)}-lambda_execution_role"
16+
name = "${lower(var.prefix)}-lambda-execution-role"
1817
assume_role_policy = jsonencode({
1918
Version = "2012-10-17",
2019
Statement = [
@@ -29,8 +28,8 @@ resource "aws_iam_role" "lambda_role" {
2928
})
3029
}
3130
resource "aws_iam_role_policy" "lambda_policy" {
32-
name = "lambda_policy"
33-
role = aws_iam_role.lambda_role.id
31+
name = "${lower(var.prefix)}-lambda-policy"
32+
role = aws_iam_role.lambda_role.id
3433
policy = jsonencode({
3534
Version = "2012-10-17",
3635
Statement = [
@@ -68,26 +67,31 @@ resource "aws_iam_role_policy" "lambda_policy" {
6867
]
6968
})
7069
}
70+
resource "aws_cloudwatch_log_group" "lambda_log_group" {
71+
count = 2
72+
name = "/aws/lambda/${lower(var.prefix)}-${element(["generate-presigned-url", "process-s3-event"], count.index)}"
73+
retention_in_days = 14
74+
}
7175
resource "aws_lambda_function" "generate_presigned_url" {
72-
filename = "generate_presigned_url.zip"
73-
function_name = "generate_presigned_url"
74-
role = aws_iam_role.lambda_role.arn
75-
handler = "generate_presigned_url.lambda_handler"
76-
runtime = "python3.8"
77-
timeout = 30
76+
filename = "generate_presigned_url.zip"
77+
function_name = "${lower(var.prefix)}-generate-presigned-url"
78+
role = aws_iam_role.lambda_role.arn
79+
handler = "generate_presigned_url.lambda_handler"
80+
runtime = "python3.12"
81+
timeout = 30
7882
environment {
7983
variables = {
8084
BUCKET_NAME = aws_s3_bucket.upload_bucket.bucket
8185
}
8286
}
8387
}
8488
resource "aws_lambda_function" "process_s3_event" {
85-
filename = "process_s3_event.zip"
86-
function_name = "process_s3_event"
87-
role = aws_iam_role.lambda_role.arn
88-
handler = "process_s3_event.lambda_handler"
89-
runtime = "python3.8"
90-
timeout = 60
89+
filename = "process_s3_event.zip"
90+
function_name = "${lower(var.prefix)}-process-s3-event"
91+
role = aws_iam_role.lambda_role.arn
92+
handler = "process_s3_event.lambda_handler"
93+
runtime = "python3.12"
94+
timeout = 60
9195
environment {
9296
variables = {
9397
SNS_TOPIC_ARN = aws_sns_topic.sns_topic.arn
@@ -102,14 +106,14 @@ resource "aws_s3_bucket_notification" "s3_bucket_notification" {
102106
}
103107
}
104108
resource "aws_lambda_permission" "allow_s3" {
105-
statement_id = "AllowS3InvokeLambda"
109+
statement_id = "${lower(var.prefix)}-allow-s3-invoke-lambda"
106110
action = "lambda:InvokeFunction"
107111
function_name = aws_lambda_function.process_s3_event.function_name
108112
principal = "s3.amazonaws.com"
109113
source_arn = aws_s3_bucket.upload_bucket.arn
110114
}
111115
resource "aws_api_gateway_rest_api" "api" {
112-
name = "PresignedURLAPI"
116+
name = "${lower(var.prefix)}-presigned-url-api"
113117
description = "API for generating presigned URLs"
114118
}
115119
resource "aws_api_gateway_resource" "resource" {
@@ -132,14 +136,46 @@ resource "aws_api_gateway_integration" "integration" {
132136
uri = "arn:aws:apigateway:${var.region}:lambda:path/2015-03-31/functions/${aws_lambda_function.generate_presigned_url.arn}/invocations"
133137
}
134138
resource "aws_lambda_permission" "allow_api_gateway" {
135-
statement_id = "AllowAPIGatewayInvoke"
139+
statement_id = "${lower(var.prefix)}-allow-api-gateway-invoke"
136140
action = "lambda:InvokeFunction"
137141
function_name = aws_lambda_function.generate_presigned_url.function_name
138142
principal = "apigateway.amazonaws.com"
139143
source_arn = "${aws_api_gateway_rest_api.api.execution_arn}/*/*"
140144
}
141145
resource "aws_api_gateway_deployment" "deployment" {
142-
depends_on = [aws_api_gateway_integration.integration]
146+
depends_on = [aws_api_gateway_integration.integration]
143147
rest_api_id = aws_api_gateway_rest_api.api.id
144-
stage_name = "dev"
148+
stage_name = "dev"
149+
}
150+
output "api_id" {
151+
description = "The ID of the API Gateway REST API"
152+
value = aws_api_gateway_rest_api.api.id
153+
}
154+
output "region" {
155+
description = "The AWS region where resources are deployed"
156+
value = var.region
157+
}
158+
output "s3_bucket_name" {
159+
description = "The name of the S3 bucket"
160+
value = aws_s3_bucket.upload_bucket.bucket
161+
}
162+
output "sns_topic_arn" {
163+
description = "The ARN of the SNS topic"
164+
value = aws_sns_topic.sns_topic.arn
165+
}
166+
output "lambda_generate_presigned_url_arn" {
167+
description = "The ARN of the generate_presigned_url Lambda function"
168+
value = aws_lambda_function.generate_presigned_url.arn
169+
}
170+
output "lambda_process_s3_event_arn" {
171+
description = "The ARN of the process_s3_event Lambda function"
172+
value = aws_lambda_function.process_s3_event.arn
173+
}
174+
output "lambda_generate_presigned_url_log_group" {
175+
description = "The name of the CloudWatch log group for the generate_presigned_url Lambda function"
176+
value = aws_cloudwatch_log_group.lambda_log_group[0].name
177+
}
178+
output "lambda_process_s3_event_log_group" {
179+
description = "The name of the CloudWatch log group for the process_s3_event Lambda function"
180+
value = aws_cloudwatch_log_group.lambda_log_group[1].name
145181
}

0 commit comments

Comments
 (0)