diff --git a/example-projects/counter-demo/aws-lambda/invoke-function.py b/example-projects/counter-demo/aws-lambda/invoke-function.py index 46a9b93..6a595a3 100644 --- a/example-projects/counter-demo/aws-lambda/invoke-function.py +++ b/example-projects/counter-demo/aws-lambda/invoke-function.py @@ -1,5 +1,6 @@ -import boto3 +from datetime import date import json +import boto3 ################################################################################################ # @@ -31,7 +32,7 @@ try: Payload='{ "input": "1" }' ) except lClient.exceptions.ResourceNotFoundException: - print('Function not available. No need to delete it.') + print('Function not available.') streamingBody = response['Payload'] result = streamingBody.read() diff --git a/example-projects/counter-demo/aws-lambda/lambda_function.py b/example-projects/counter-demo/aws-lambda/lambda_function.py index 52c31d7..a017758 100644 --- a/example-projects/counter-demo/aws-lambda/lambda_function.py +++ b/example-projects/counter-demo/aws-lambda/lambda_function.py @@ -1,11 +1,20 @@ # import json import base64 +import os import boto3 def lambda_handler(event, context): + print('## ENVIRONMENT VARIABLES') + print(os.environ) + print('## EVENT') + print(event) + + globally_unique_s3_group_bucket_name = os.environ.get("bucketName") + print('Trying to access bucket: ' + globally_unique_s3_group_bucket_name) + s3_client = boto3.client('s3') - response = s3_client.get_object(Bucket='cloudcomp-counter', Key='us-east-1') + response = s3_client.get_object(Bucket=globally_unique_s3_group_bucket_name, Key='us-east-1') counter = int(response['Body'].read().decode('utf-8')) @@ -20,11 +29,11 @@ def lambda_handler(event, context): if incr is not 0: counter = counter + incr - response = s3_client.put_object(Bucket='cloudcomp-counter', Key='us-east-1', Body=str(counter)) + response = s3_client.put_object(Bucket=globally_unique_s3_group_bucket_name, Key='us-east-1', Body=str(counter)) - output = ('TCPTimeCounter REST Service\n' - '\n' - '

HS Fulda - TCPTimeCounter REST Service

\n' + output = ('Counter Demo\n' + # '\n' + '

HS Fulda Cloud Computing - Counter Demo

\n' '

HTML-Output: ' + str(counter) + '

\n' '
\n' '\n' diff --git a/example-projects/counter-demo/aws-lambda/start.py b/example-projects/counter-demo/aws-lambda/start.py index d43dffb..06c7e77 100644 --- a/example-projects/counter-demo/aws-lambda/start.py +++ b/example-projects/counter-demo/aws-lambda/start.py @@ -1,5 +1,7 @@ -import boto3 +from datetime import date import zipfile +import boto3 +from botocore.exceptions import ClientError ################################################################################################ # @@ -11,11 +13,21 @@ import zipfile # bucket names need to be world wide unique ;) The demo looks for a file that is named # "us-east-1" (same as our default region) in the bucket and expects a number in it to increase +groupNr = 22 +currentYear = date.today().year + +globallyUniqueS3GroupBucketName = "cloudcomp-counter-" + str(currentYear) + "-group" + str(groupNr) + # region = 'eu-central-1' region = 'us-east-1' functionName = 'cloudcomp-counter-lambda-demo' + +# see ARN for AWS Academy LabRole function here: +# https://us-east-1.console.aws.amazon.com/iamv2/home?region=us-east-1#/roles/details/LabRole?section=permissions + # roleName = 'arn:aws:iam::309000625112:role/service-role/cloudcomp-counter-demo-role-6rs7pah3' -roleName = 'arn:aws:iam::919927306708:role/cloudcomp-s3-access' +# roleName = 'arn:aws:iam::919927306708:role/cloudcomp-s3-access' +roleName = 'arn:aws:iam::488766701848:role/LabRole' ################################################################################################ # @@ -23,12 +35,21 @@ roleName = 'arn:aws:iam::919927306708:role/cloudcomp-s3-access' # ################################################################################################ +def cleanup_s3_bucket(s3_bucket): + # Deleting objects + for s3_object in s3_bucket.objects.all(): + s3_object.delete() + # Deleting objects versions if S3 versioning enabled + for s3_object_ver in s3_bucket.object_versions.all(): + s3_object_ver.delete() + client = boto3.setup_default_session(region_name=region) +s3Client = boto3.client('s3') +s3Resource = boto3.resource('s3') lClient = boto3.client('lambda') apiClient = boto3.client("apigatewayv2") - print("Deleting old function...") print("------------------------------------") try: @@ -38,6 +59,24 @@ try: except lClient.exceptions.ResourceNotFoundException: print('Function not available. No need to delete it.') +print("Deleting old bucket...") +print("------------------------------------") + +try: + currentBucket = s3Resource.Bucket(globallyUniqueS3GroupBucketName) + cleanup_s3_bucket(currentBucket) + currentBucket.delete() +except ClientError as e: + print(e) + +print("creating S3 bucket (must be globally unique)...") +print("------------------------------------") + +try: + response = s3Client.create_bucket(Bucket=globallyUniqueS3GroupBucketName) + response = s3Client.put_object(Bucket=globallyUniqueS3GroupBucketName, Key='us-east-1', Body=str(0)) +except ClientError as e: + print(e) print("creating new function...") print("------------------------------------") @@ -52,27 +91,53 @@ with open('lambda-deployment-archive.zip', mode='rb') as file: response = lClient.create_function( FunctionName=functionName, - Runtime='python3.8', + Runtime='python3.9', Role=roleName, Code={ 'ZipFile': zipfileContent }, Handler='lambda_function.lambda_handler', Publish=True, + Environment={ + 'Variables': { + 'bucketName': globallyUniqueS3GroupBucketName + } + } ) lambdaFunctionARN = response['FunctionArn'] -print("creating API gateway...") -print("------------------------------------") +print("Lambda Function and S3 Bucket to store the counter are available. Sadly, AWS Academy labs do not allow\n" + "creating an API gateway to be able to access the Lambda function directly via HTTP from the browser, as\n" + "shown in https://348yxdily0.execute-api.eu-central-1.amazonaws.com/default/cloudcomp-counter-demo.\n" + "\n" + "However you can now run invoke-function.py to view an increment the counter. You can also use \n" + "the test button in the Lambda AWS console. In this case you need to send the content\n" + "\n" + "{\n" + " \"input\": \"1\"\n" + "}\n" + "\n" + "to increment the counter by 1.\n" + "Try to understand how Lambda can be used to cut costs regarding cloud services and what its pros\n" + "and cons are.\n") + +# sadly, AWS Academy Labs don't allow API gateways +# API gateway would allow getting an HTTP endpoint that we could access directly in the browser, +# that would call our function, as in the provided demo: +# +# https://348yxdily0.execute-api.eu-central-1.amazonaws.com/default/cloudcomp-counter-demo -#apiArn = "" -response = apiClient.create_api( - Name=functionName + '-api', - ProtocolType='HTTP', - Target=lambdaFunctionARN -) -#apiArn=response[''] - -#response = lClient.create_event_source_mapping( -# EventSourceArn=apiArn, -#) \ No newline at end of file +# print("creating API gateway...") +# print("------------------------------------") +# +# #apiArn = "" +# response = apiClient.create_api( +# Name=functionName + '-api', +# ProtocolType='HTTP', +# Target=lambdaFunctionARN +# ) +# #apiArn=response[''] +# +# #response = lClient.create_event_source_mapping( +# # EventSourceArn=apiArn, +# #) \ No newline at end of file diff --git a/example-projects/counter-demo/aws-lambda/stop.py b/example-projects/counter-demo/aws-lambda/stop.py index ba47801..576954f 100644 --- a/example-projects/counter-demo/aws-lambda/stop.py +++ b/example-projects/counter-demo/aws-lambda/stop.py @@ -1,5 +1,4 @@ import boto3 -import zipfile ################################################################################################ #