/aws/

AWS Cloud Formation (example 9)

2020-04-16 22:08:31

  • S3::Bucket
  • Lambda::Permission
  • IAM::Role
    • Policy::AWSLambdaVPCLogsAccess
    • Policy::AWSLambdaS3Access
    • Policy::AWSLambdaToLambdaAccess
  • Lambda::Function
AWSTemplateFormatVersion: 2010-09-09

Description: 'Lambda Function'

Parameters:
  ParameterSourceBucketName:
    Type: String
    Default: 'bucket-name.source'

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Buckets"
        Parameters:
          - ParameterSourceBucketName
    ParameterLabels:
      ParameterSourceBucketName:
        default: "Source Bucket - Location for txt files"

Resources:
  SourceTarget:
    Type: 'AWS::S3::Bucket'
    DeletionPolicy: Retain
    Properties:
      BucketName: !Ref ParameterSourceBucketName
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true
      BucketEncryption:
        ServerSideEncryptionConfiguration:
        - ServerSideEncryptionByDefault:
            SSEAlgorithm: AES256
      NotificationConfiguration:
        LambdaConfigurations:
        - Event: 's3:ObjectCreated:*'
          Filter:
            S3Key:
              Rules:
              - Name: suffix
                Value: txt
          Function: !GetAtt S3EventLambdaFunction.Arn

  S3InvokeLambdaPermission:
    Type: 'AWS::Lambda::Permission'
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref S3EventLambdaFunction
      Principal: s3.amazonaws.com
      SourceArn: !Sub arn:aws:s3:::${ParameterSourceBucketName}

  LambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - lambda.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: !Join ['', [!Ref "AWS::StackName", "-AWSLambdaVPCLogsAccess" ]]
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Resource: arn:aws:logs:*:*:*
      - PolicyName: !Join ['', [!Ref "AWS::StackName", "AWSLambdaS3Access" ]]
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - s3:GetObject
            - s3:PutObject
            Resource: arn:aws:s3:::*
      - PolicyName: !Join ['', [!Ref "AWS::StackName", "AWSLambdaToLambdaAccess" ]]
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - lambda:InvokeFunction
            Resource: "*"

  S3EventLambdaFunction:
    Type: "AWS::Lambda::Function"
    Properties:
      FunctionName: !Join ['-', [!Ref "AWS::StackName", "S3EventHandler" ]]
      Description: S3 Event Handler
      Role: !GetAtt LambdaRole.Arn
      Handler: index.lambda_handler
      Code:
        ZipFile: |
          import os
          import boto3
          import urllib
          import logging

          VERSION = '1.0 (S3 Event Handler)'
          ENV_SOURCE_BUCKET_NAME = os.environ['SOURCE_BUCKET_NAME']
          ENV_TEST_VARIABLE = os.environ['TEST_VARIABLE']


          def get_bucket_name(e): return e['Records'][0]['s3']['bucket']['name']


          def get_key_file_name(e): return urllib.parse.unquote_plus(e['Records'][0]['s3']['object']['key'], encoding='utf-8')


          def is_txt_file(key): return key.endswith("txt")


          def get_s3_text_object(e):
              try:
                  aws = boto3.client('s3')
                  bucket = get_bucket_name(e)
                  key = get_key_file_name(e)
                  r = aws.get_object(Bucket=bucket, Key=key)
                  body = r["Body"].read().decode()
                  return {
                      'key': key,
                      'raw': body
                  }
              except Exception as e:
                  logging.exception('Get text object fail')


          def lambda_handler(e, c):
              print("Version {}".format(VERSION))
              print("Env Source bucket name {}".format(ENV_SOURCE_BUCKET_NAME))
              print("Env Test variable {}".format(ENV_TEST_VARIABLE))
              key = get_key_file_name(e)
              if is_txt_file(key):
                  s3_object = get_s3_text_object(e)
                  print(s3_object)
              else:
                  print('Provided file {} is not valid'.format(key))
      Runtime: python3.6
      Environment:
        Variables:
          SOURCE_BUCKET_NAME: !Ref ParameterSourceBucketName
          TEST_VARIABLE: 'lorem ipsum'
      MemorySize: 128
      Timeout: 30