-
Notifications
You must be signed in to change notification settings - Fork 914
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1388 from akkumaha/akkumaha-feature-lambda-s3-pol…
…ly-cdk New Serverless Pattern - Lambda-S3-Polly-CDK
- Loading branch information
Showing
8 changed files
with
284 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# S3 Triggered Lambda Function that starts an Amazon Polly Task and points to another S3 bucket for results | ||
|
||
This repo contains serverless patterns showing how to setup a Lambda with an S3 *object created* trigger that starts a basic, Amazon Polly Task. The resulting speech is placed into another S3 bucket. | ||
|
||
![Demo Project Solution Architecture Diagram](architecture.png) | ||
|
||
- Learn more about these patterns at https://serverlessland.com/patterns. | ||
- To learn more about submitting a pattern, read the [publishing guidelines page](https://github.com/aws-samples/serverless-patterns/blob/main/PUBLISHING.md). | ||
|
||
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. | ||
|
||
## Requirements | ||
|
||
* AWS Account | ||
* AWS CLI already configured with Administrator permission | ||
* [NodeJS 14.x installed](https://nodejs.org/en/download/) | ||
* CDK v2 installed: See Getting Started With the AWS CDK | ||
* Python CDK required libraries: (install with pip install -r requirements.txt) | ||
* Clone this repo! | ||
|
||
## Deployment Instructions | ||
|
||
1. Within your CDK Python module directory(where all your cdk stacks are located) create a constructs folder and within the constructs folder, create an assets folder. | ||
2. Place the `amazon-polly-stack.py` file in the constructs folder you created and the `file-uploaded-trigger` folder in the assets folder you created. | ||
3. In your terminal run `CDK Deploy` for the specified stack that uses this construct | ||
|
||
### Removing the resources | ||
|
||
1. run `CDK Destroy <stack id>` for the specified stack that used this construct | ||
|
||
``` | ||
git clone https://github.com/aws-samples/serverless-patterns/lambda-s3-polly-cdk | ||
``` | ||
|
||
Each subdirectory contains additional installation and usage instructions. | ||
|
||
---- | ||
Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
---- | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#!/usr/bin/env python3 | ||
import os | ||
|
||
import aws_cdk as cdk | ||
|
||
from pattern.amazon_polly_stack import AmazonPollyStack | ||
|
||
|
||
app = cdk.App() | ||
AmazonPollyStack(app, "AmazonPollyStack", | ||
# If you don't specify 'env', this stack will be environment-agnostic. | ||
# Account/Region-dependent features and context lookups will not work, | ||
# but a single synthesized template can be deployed anywhere. | ||
|
||
# Uncomment the next line to specialize this stack for the AWS Account | ||
# and Region that are implied by the current CLI configuration. | ||
|
||
#env=cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION')), | ||
|
||
# Uncomment the next line if you know exactly what Account and Region you | ||
# want to deploy the stack to. */ | ||
|
||
#env=cdk.Environment(account='123456789012', region='us-east-1'), | ||
|
||
# For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html | ||
) | ||
|
||
app.synth() |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
{ | ||
"app": "python3 app.py", | ||
"watch": { | ||
"include": [ | ||
"**" | ||
], | ||
"exclude": [ | ||
"README.md", | ||
"cdk*.json", | ||
"requirements*.txt", | ||
"source.bat", | ||
"**/__init__.py", | ||
"python/__pycache__", | ||
"tests" | ||
] | ||
}, | ||
"context": { | ||
"@aws-cdk/aws-lambda:recognizeLayerVersion": true, | ||
"@aws-cdk/core:checkSecretUsage": true, | ||
"@aws-cdk/core:target-partitions": [ | ||
"aws", | ||
"aws-cn" | ||
], | ||
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, | ||
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, | ||
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, | ||
"@aws-cdk/aws-iam:minimizePolicies": true, | ||
"@aws-cdk/core:validateSnapshotRemovalPolicy": true, | ||
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, | ||
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, | ||
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, | ||
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true, | ||
"@aws-cdk/core:enablePartitionLiterals": true, | ||
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, | ||
"@aws-cdk/aws-iam:standardizedServicePrincipals": true, | ||
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, | ||
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, | ||
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, | ||
"@aws-cdk/aws-route53-patters:useCertificate": true, | ||
"@aws-cdk/customresources:installLatestAwsSdkDefault": false, | ||
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, | ||
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, | ||
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, | ||
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, | ||
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, | ||
"@aws-cdk/aws-redshift:columnId": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
{ | ||
"title": "S3 to Lambda to Polly", | ||
"description": "Create a Lambda with an S3 object created trigger that starts an Amazon Polly Task and puts the results in anoter S3 Bucket", | ||
"language": "Python", | ||
"level": "200", | ||
"framework": "CDK", | ||
"introBox": { | ||
"headline": "How it works", | ||
"text": [ | ||
"This pattern contains a sample AWS Cloud Development Kit (AWS CDK) template that deploys a Lambda Function with an S3 object created trigger to start an Amazon Polly Task and place the results in another S3 bucket.", | ||
"This pattern deploys one Lambda Function and two S3 Buckets." | ||
] | ||
}, | ||
"gitHub": { | ||
"template": { | ||
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/lambda-s3-polly-cdk", | ||
"templateURL": "serverless-patterns/lambda-s3-polly-cdk", | ||
"projectFolder": "pattern", | ||
"templateFile": "assets/lambda-s3-polly-cdk.py" | ||
} | ||
}, | ||
"resources": { | ||
"bullets": [ | ||
{ | ||
"text": "Using an Amazon S3 trigger to invoke a Lambda function", | ||
"link": "https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example.html" | ||
}, | ||
{ | ||
"text": "Guidelines and quotas - Amazon Polly", | ||
"link": "https://docs.aws.amazon.com/polly/latest/dg/limits.html" | ||
} | ||
] | ||
}, | ||
"deploy": { | ||
"text": [ | ||
"cdk deploy" | ||
] | ||
}, | ||
"testing": { | ||
"text": [ | ||
"See the Github repo for detailed testing instructions." | ||
] | ||
}, | ||
"cleanup": { | ||
"text": [ | ||
"Delete the stack: <code>cdk delete</code>." | ||
] | ||
}, | ||
"authors": [ | ||
{ | ||
"name": "Kranthi Kiran A", | ||
"image": "https://media.licdn.com/dms/image/C5603AQGMzL2iVESvpA/profile-displayphoto-shrink_400_400/0/1662286284377?e=1691020800&v=beta&t=p7litfMASeNBNU-Xeb7bpl5WD8KoWrlVd3Azl3_q1bg", | ||
"bio": "Kranthi is an Associate Cloud Developer with Amazon Web Services", | ||
"linkedin": "https://www.linkedin.com/in/akkiran003/" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
from aws_cdk import ( | ||
# Duration, | ||
Stack, | ||
aws_s3 as s3, | ||
aws_lambda as lambda_, | ||
aws_iam as iam, | ||
Duration, | ||
aws_lambda_event_sources as eventsources | ||
) | ||
from constructs import Construct | ||
|
||
class AmazonPollyStack(Stack): | ||
|
||
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: | ||
super().__init__(scope, construct_id, **kwargs) | ||
|
||
#Input Bucket | ||
self.input_bucket = s3.Bucket(self, "input-bucket", | ||
versioned=True, | ||
encryption=s3.BucketEncryption.S3_MANAGED, | ||
block_public_access=s3.BlockPublicAccess.BLOCK_ALL, | ||
enforce_ssl=True) | ||
|
||
# Destination Bucket | ||
self.destination_bucket = s3.Bucket(self, 'destination-bucket', | ||
versioned=True, | ||
encryption=s3.BucketEncryption.S3_MANAGED, | ||
block_public_access=s3.BlockPublicAccess.BLOCK_ALL, | ||
enforce_ssl=True) | ||
|
||
python_lambda_kwargs = { | ||
'handler': 'lambda_function.lambda_handler', | ||
'runtime': lambda_.Runtime.PYTHON_3_9, | ||
'timeout': Duration.minutes(2) | ||
} | ||
|
||
# Trigger Transcription Lambda | ||
trigger_polly_lambda = lambda_.Function(self, "file-upload-trigger", **python_lambda_kwargs, | ||
code=lambda_.Code.from_asset( | ||
'./pattern/assets'), | ||
function_name="start-polly", | ||
initial_policy=[ | ||
iam.PolicyStatement( | ||
actions=['polly:SynthesizeSpeech'], | ||
resources=['*']), | ||
iam.PolicyStatement(actions=['s3:PutObject'], | ||
resources=[ | ||
self.destination_bucket.bucket_arn+'/*'] | ||
), | ||
iam.PolicyStatement(actions=['s3:GetObject', | ||
's3:ListBucket'], | ||
resources=[ | ||
self.input_bucket.bucket_arn, | ||
self.input_bucket.bucket_arn + '/*' | ||
] | ||
) | ||
] | ||
) | ||
|
||
# Add Trigger and Environment Variable | ||
trigger_polly_lambda.add_event_source(eventsources.S3EventSource(self.input_bucket, events=[s3.EventType.OBJECT_CREATED])) | ||
trigger_polly_lambda.add_environment('DESTINATION_BUCKET', self.destination_bucket.bucket_name) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import json | ||
import boto3 | ||
import os | ||
from tempfile import gettempdir | ||
from contextlib import closing | ||
|
||
# Get the s3 client | ||
s3 = boto3.client("s3") | ||
# Create a client to use Polly | ||
polly_client = boto3.client("polly") | ||
|
||
output_bucket = os.environ['DESTINATION_BUCKET'] | ||
|
||
def lambda_handler(event, context): | ||
|
||
# Get the s3 bucket name | ||
bucket_name = event["Records"][0]["s3"]["bucket"]["name"] | ||
# Get the file name | ||
file_name = event["Records"][0]["s3"]["object"]["key"] | ||
# Get the file object | ||
file_obj = s3.get_object(Bucket=bucket_name, Key=file_name) | ||
# Read the file | ||
file_content = file_obj["Body"].read().decode("utf-8") | ||
|
||
# Call the Polly API to convert the text to speech | ||
response = polly_client.synthesize_speech( | ||
Text=file_content, | ||
OutputFormat="mp3", | ||
VoiceId="Joanna" | ||
) | ||
print(response) | ||
# Get the audio file | ||
audio_file = response["AudioStream"] | ||
# Save the audio file to the s3 bucket | ||
audio_file_name = file_name.split(".")[0] + ".mp3" | ||
print(audio_file_name) | ||
with closing(audio_file) as stream: | ||
s3.put_object(Key=audio_file_name, Body=stream.read(), Bucket=output_bucket) | ||
##s3.put_object(Bucket=bucket_name, Key=audio_file_name, Body=file) | ||
##with open(audio_file, 'rb') as data: | ||
## s3.upload_fileobj(data, bucket_name, audio_file_name) | ||
return { | ||
"statusCode": 200, | ||
"body": json.dumps({ | ||
"message": "Converted the text to speech" | ||
}), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
aws-cdk-lib==2.70.0 | ||
constructs>=10.0.0,<11.0.0 |