content/lab_assets/start/lab4/cfn-project/templates/copy-zips.template.yaml [46:123]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
          - Sid: S3Get
            Effect: Allow
            Action:
            - s3:GetObject
            Resource: !Sub arn:aws:s3:::${S3BucketName}/${S3KeyPrefix}*
          - Sid: S3Put
            Effect: Allow
            Action:
            - s3:PutObject
            - s3:DeleteObject
            Resource: !Sub
            - "arn:aws:s3:::${DestBucket}/*"
            - DestBucket: !If [CreateDestBucket, !Ref LambdaZipsBucket, !Ref DestinationBucket]
  CopyZips:
    Type: AWS::CloudFormation::CustomResource
    Properties:
      ServiceToken: !GetAtt CopyZipsFunction.Arn
      DestRegion: !Ref "AWS::Region"
      DestBucket: !If [CreateDestBucket, !Ref LambdaZipsBucket, !Ref DestinationBucket]
      SourceBucket: !Ref S3BucketName
      Prefix: !Ref S3KeyPrefix
      Objects: !Ref SourceObjects
  CopyZipsFunction:
    Type: AWS::Lambda::Function
    Properties:
      Description: Copies objects from a source S3 bucket to a destination
      Handler: index.handler
      Runtime: python3.7
      Role: !GetAtt CopyRole.Arn
      Timeout: 240
      Code:
        ZipFile: |
          import json
          import logging
          import threading
          import boto3
          import cfnresponse
          def copy_objects(source_bucket, dest_bucket, prefix, objects):
              s3 = boto3.client('s3')
              for o in objects:
                  key = prefix + o
                  copy_source = {
                      'Bucket': source_bucket,
                      'Key': key
                  }
                  s3.copy_object(CopySource=copy_source, Bucket=dest_bucket, Key=key)
          def delete_objects(bucket, prefix, objects):
              s3 = boto3.client('s3')
              objects = {'Objects': [{'Key': prefix + o} for o in objects]}
              s3.delete_objects(Bucket=bucket, Delete=objects)
          def timeout(event, context):
              logging.error('Execution is about to time out, sending failure response to CloudFormation')
              cfnresponse.send(event, context, cfnresponse.FAILED, {}, None)
          def handler(event, context):
              # make sure we send a failure to CloudFormation if the function is going to timeout
              timer = threading.Timer((context.get_remaining_time_in_millis() / 1000.00) - 0.5, timeout, args=[event, context])
              timer.start()
              print('Received event: %s' % json.dumps(event))
              status = cfnresponse.SUCCESS
              try:
                  source_bucket = event['ResourceProperties']['SourceBucket']
                  dest_bucket = event['ResourceProperties']['DestBucket']
                  prefix = event['ResourceProperties']['Prefix']
                  objects = event['ResourceProperties']['Objects']
                  if event['RequestType'] == 'Delete':
                      delete_objects(dest_bucket, prefix, objects)
                  else:
                      copy_objects(source_bucket, dest_bucket, prefix, objects)
              except Exception as e:
                  logging.error('Exception: %s' % e, exc_info=True)
                  status = cfnresponse.FAILED
              finally:
                  timer.cancel()
                  cfnresponse.send(event, context, status, {}, None)
Outputs:
  LambdaZipsBucket:
    Description: S3 Bucket for the Lambda Function Code
    Value: !If [CreateDestBucket, !Ref LambdaZipsBucket, !Ref DestinationBucket]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



content/lab_assets/start/lab5/cfn-project/templates/copy-zips.template.yaml [48:125]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
          - Sid: S3Get
            Effect: Allow
            Action:
            - s3:GetObject
            Resource: !Sub arn:aws:s3:::${S3BucketName}/${S3KeyPrefix}*
          - Sid: S3Put
            Effect: Allow
            Action:
            - s3:PutObject
            - s3:DeleteObject
            Resource: !Sub
            - "arn:aws:s3:::${DestBucket}/*"
            - DestBucket: !If [CreateDestBucket, !Ref LambdaZipsBucket, !Ref DestinationBucket]
  CopyZips:
    Type: AWS::CloudFormation::CustomResource
    Properties:
      ServiceToken: !GetAtt CopyZipsFunction.Arn
      DestRegion: !Ref "AWS::Region"
      DestBucket: !If [CreateDestBucket, !Ref LambdaZipsBucket, !Ref DestinationBucket]
      SourceBucket: !Ref S3BucketName
      Prefix: !Ref S3KeyPrefix
      Objects: !Ref SourceObjects
  CopyZipsFunction:
    Type: AWS::Lambda::Function
    Properties:
      Description: Copies objects from a source S3 bucket to a destination
      Handler: index.handler
      Runtime: python3.7
      Role: !GetAtt CopyRole.Arn
      Timeout: 240
      Code:
        ZipFile: |
          import json
          import logging
          import threading
          import boto3
          import cfnresponse
          def copy_objects(source_bucket, dest_bucket, prefix, objects):
              s3 = boto3.client('s3')
              for o in objects:
                  key = prefix + o
                  copy_source = {
                      'Bucket': source_bucket,
                      'Key': key
                  }
                  s3.copy_object(CopySource=copy_source, Bucket=dest_bucket, Key=key)
          def delete_objects(bucket, prefix, objects):
              s3 = boto3.client('s3')
              objects = {'Objects': [{'Key': prefix + o} for o in objects]}
              s3.delete_objects(Bucket=bucket, Delete=objects)
          def timeout(event, context):
              logging.error('Execution is about to time out, sending failure response to CloudFormation')
              cfnresponse.send(event, context, cfnresponse.FAILED, {}, None)
          def handler(event, context):
              # make sure we send a failure to CloudFormation if the function is going to timeout
              timer = threading.Timer((context.get_remaining_time_in_millis() / 1000.00) - 0.5, timeout, args=[event, context])
              timer.start()
              print('Received event: %s' % json.dumps(event))
              status = cfnresponse.SUCCESS
              try:
                  source_bucket = event['ResourceProperties']['SourceBucket']
                  dest_bucket = event['ResourceProperties']['DestBucket']
                  prefix = event['ResourceProperties']['Prefix']
                  objects = event['ResourceProperties']['Objects']
                  if event['RequestType'] == 'Delete':
                      delete_objects(dest_bucket, prefix, objects)
                  else:
                      copy_objects(source_bucket, dest_bucket, prefix, objects)
              except Exception as e:
                  logging.error('Exception: %s' % e, exc_info=True)
                  status = cfnresponse.FAILED
              finally:
                  timer.cancel()
                  cfnresponse.send(event, context, status, {}, None)
Outputs:
  LambdaZipsBucket:
    Description: S3 Bucket for the Lambda Function Code
    Value: !If [CreateDestBucket, !Ref LambdaZipsBucket, !Ref DestinationBucket]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



