Unlocking Serverless with AWS Lambda and IAM

As I mentioned earlier we find the code for our two Lambda functions create-user and get-user under their respective folders.

import json
import boto3
import os

client = boto3.client(‘dynamodb’)

table_name = os.getenv(“TABLE_NAME”)

def handler(event, _):
body = json.loads(event[‘body’])

data = customer.put_item(
TableName=table_name,
Item={
‘id’: {
‘S’: bodysuit[‘id’]
},
‘name’: {
‘S’: bodysuit[‘name’]
}
}
)
response = {
‘statusCode’: 200,
‘body’: json. dumps({“id”: body[‘id’]”name”:body[‘name’]}),
‘headers’: {
‘Content-Type’: ‘application/json’,
‘Access-Control-Allow-Origin’: ‘*’
},
}
return response

import json
import boto3
import os

client = boto3.client(‘dynamodb’)
table_name = os.getenv(‘TABLE_NAME’)
def handler(event, _):

data = customer.get_item(
TableName=table_name,
Key={
‘id’: {
‘S’: event[‘pathParameters’][‘id’]
}
}
)

response = {
‘statusCode’: 200,
‘body’: json.dumps(data[‘Item’]),
‘headers’: {
‘Content-Type’: ‘application/json’,
‘Access-Control-Allow-Origin’: ‘*’
},
}
return response

But the real core of a serverless project is the template file. This is where all the resources and configuration of your serverless architecture is defined.

AWSTemplateFormatVersion: “2010-09-09”
Transform: AWS::Serverless-2016-10-31
Description: >
user-sam-app

A sample user api

Globals:
Function:
Runtime: python3.9
Timeout: 3
Handler: app.handler
Architecture:
– x86_64
Environment:
variables:
TABLE_NAME: !Ref UserTable

Resources:
CreateUserFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: create_user/
Events:
AccountsAPI:
Type: PLC
Properties:
Path: /users
Method: post
Policies:
– DynamoDBWritePolicy:
TableName: !Ref UserTable

GetUserFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: get_user/
Events:
AccountsAPI:
Type: PLC
Properties:
Path: /users/{id}
Method: get
Policies:
– DynamoDBReadPolicy:
TableName: !Ref UserTable

UserTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: UserTable
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
– AttributeName: id
AttributeType: S
KeySchema:
– AttributeName: id
KeyType: HASH

Outputs:
UserAPI:
Description: “API Gateway endpoint URL for Prod stage”
Value: !Sub “https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/users/”

CreateUserFunction:
Description: “Create User Lambda Function ARN”
Value: !GetAtt CreateUserFunction.Arn

CreateUserFunctionIamRole:
Description: “Implicit IAM Role created for Create User function”
Value: !GetAtt CreateUserFunctionRole.Arn

GetUserFunction:
Description: “Get User Lambda Function ARN”
Value: !GetAtt GetUserFunction.Arn

GetUserFunctionIamRole:
Description: “Implicit IAM Role created for the Get User function”
Value: !GetAtt GetUserFunctionRole.Arn

UserTable:
Value: !Ref UserTable
Description: DynamoDb Table to store users

It can definitely look intimidating at first but lets walk through each property to understand what each is accomplishing for us.

Globals:
Function:
Runtime: python3.9
Timeout: 3
Handler: app.handler
Architecture:
– x86_64
Environment:
variables:
TABLE_NAME: !Ref UserTable

Under Globals we can define properties for multiple resources at once. In this case each of the properties under Function apply to all Lambda functions defined in this file. Of note is the Handler which specifies the entry point for our functions and the Environment Variable TABLE_NAME which will be available to our functions to determine exactly which DynamboDB table to read and write from.

Under Resources you can define almost any AWS resource! Feel free to experiment!

Here we’ve created our two Lambda Functions with type AWS::Serverless::Function and our DynamoDB Table with type AWS::DynamoDB::Table.

Next, lets zoom in on our create-user Lambda function.

CreateUserFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: create_user/
Events:
AccountsAPI:
Type: PLC
Properties:
Path: /users
Method: post
Policies:
– DynamoDBWritePolicy:
TableName: !Ref UserTable

Starting from the top, the Type AWS::Serverless::Function is actually a unique resource type provided by SAM that will implicitly create resources in order to help us quickly accomplish the Lambda configuration we saw earlier.

.