We will create a Lambda function that deletes all items with the specified partition key and sort key in the DynamoDB table. It also deletes the corresponding image file from the S3 bucket.
Open the template.yaml file in the fcaj-book-shop folder.
Add the following resource at the end of the file to create the BookDelete Lambda function:
BookDelete:
Type: AWS::Serverless::Function
Properties:
CodeUri: fcaj-book-shop/book_delete
Handler: book_delete.lambda_handler
Runtime: python3.13
FunctionName: book_delete
Environment:
Variables:
BUCKET_NAME: !Ref BookImageResizeShop
TABLE_NAME: !Ref BooksTable
Architectures:
- x86_64
Policies:
- Statement:
- Sid: VisualEditor0
Effect: Allow
Action:
- dynamodb:DeleteItem
- dynamodb:GetItem
- dynamodb:Query
- s3:DeleteObject
Resource:
- !Sub arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${booksTableName}
- !Join
- ""
- - "arn:aws:s3:::"
- !Ref BookImageResizeShop
- /*

This resource defines a Lambda function named book_delete that:
BUCKET_NAME (pointing to the resize bucket) and TABLE_NAMEThe directory structure is as follows:
fcaj-book-shop
├── fcaj-book-shop
│ ├── books_list
│ │ └── books_list.py
│ ├── book_create
│ │ ├── book_create.py
│ │ └── requirements.txt
│ └── book_delete
│ └── book_delete.py
└── template.yaml
import boto3
import os
BUCKET = os.environ['BUCKET_NAME']
TABLE = os.environ['TABLE_NAME']
s3_client = boto3.client('s3')
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(TABLE)
header_res = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET,DELETE",
"Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token",
}
def lambda_handler(event, context):
delete_id = event.get('pathParameters', {})
delete_id['rv_id'] = 0
try:
# Get item from id
try:
delete_item = table.get_item(Key=delete_id)
image_path = delete_item['Item'].get('image', '')
image_name = image_path.split('/')[-1]
except Exception as e:
print(f"Error getting item with that {delete_id['id']}")
raise Exception(f"Error getting item with that {delete_id['id']}")
# Delete item in DynamoDB and s3 bucket
try:
items_with_same_id = table.query(
TableName=TABLE,
ProjectionExpression='rv_id',
KeyConditionExpression='id = :id',
ExpressionAttributeValues={':id': delete_id['id']}
)
for item in items_with_same_id['Items']:
delete_id['rv_id'] = item['rv_id']
table.delete_item(Key=delete_id)
s3_client.delete_object(Bucket=BUCKET, Key=image_name)
except Exception as e:
print(f"Error getting item with that {delete_id['id']}")
raise Exception(f"Error getting item with that {delete_id['id']}")
return {
'statusCode': 200,
'body': 'Successfully delete item!',
'headers': header_res
}
except Exception as e:
print(f'Error deleting item: {e}')
raise Exception(f'Error deleting item: {e}')

Run the following commands to build and validate the SAM template:
sam validate
sam build

Deploy the updated stack:
sam deploy
The changeset will show new resources being added:
BookDeleteRole (AWS::IAM::Role)BookDelete (AWS::Lambda::Function)Enter y to confirm the deployment.

Wait for the deployment to complete. You should see Successfully created/updated stack.

Open the Lambda console. You should now see three functions: books_list, book_create, and book_delete.

Click on the book_delete function. Review the Code source section.

Review the Function overview section showing the function diagram.

Click the Configuration tab, then select Permissions from the left menu. Click on the execution role name (e.g., fcaj-book-shop-BookDeleteRole-...).

At the IAM Role page, check the Permissions policies section. You should see:

Click on BookDeleteRolePolicy0 to expand it. Review the policy JSON that grants dynamodb:DeleteItem, dynamodb:GetItem, dynamodb:Query, and s3:DeleteObject permissions.
