49

AWS Lambda + Serverless Framework + Python— Part 1 : A Step By Step “Hello World...

 5 years ago
source link: https://www.tuicool.com/articles/hit/JfamquB
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

AWS Lambda + Serverless Framework + Python— Part 1 : A Step By Step “Hello World”

I am creating a series of blog posts to help you develop, deploy and run (mostly) Python applications on AWS Lambda using Serverless Framwork.

You can find my other articles about the same topic but using other frameworks like Creating a Serverless Uptime Monitor & Getting Alerted by SMS — Lambda, Zappa & Python or Creating a Serverless Python API Using AWS Lambda & Chalice

Don’t forget to subscribe to Shipped: An Independent Newsletter Focused On Serverless, Containers, FaaS & Other Interesting Stuff and take a look at Practical AWS, a training concerned with the actual use of AWS rather than with theory & ideas .

Evu2AjF.png!web

Install & Configure Python Virtual Environment

I’m using Ubuntu, so the installation steps could be used for Ubuntu, Debian and Ubuntu/Debian based distributions. For other OSs, you can find more information here , and in the official website of Python .

sudo apt-get install python3
sudo apt-get install python3-pip
sudo pip3 install virtualenv
mkdir -p serverless-python-examples/hello-world/app
cd serverless-python-examples/hello-world

Create a virtual environment and activate it:

virtualenv -p python3 venv
. venv/bin/activate

Our working directory is

serverless-python-examples/hello-world/app

Create an AWS User for Your Application

The second step is signing in to your AWS console and creating a new user. (You can also use a user you already created) :

v6Vf6n3.png!web

Now add the permissions you need for the created user. In my case, I am going to choose the Administration permission (arn:aws:iam::aws:policy/AdministratorAccess) that provides full access to AWS services and resources.

Note:When thinking about security, the administrator access is not a good choice, you can refine your user permissions by choosing only the AWS permissions you need.

zauyUvj.png!web

Please keep in mind that you must download and keep the generated credentials in a safe place:

3a2aUv7.png!web

For the sake of simplicity, I added a new profile to the file

~/.aws/credentials

with the name

serverless
AfMzUjf.png!web

By adding the credentials to the AWS credentials file, I can use any AWS command using the desired profile.

Example:

aws s3 cp my_file s3://my_bucket --profile serverless

Installing and Configuring Serverless Framework

You can install Serverless using a single command:

sudo npm install -g serverless

Let’s configure Serverless:

serverless config credentials --provider aws --key <ACCESS KEY ID> --secret <SECRET KEY>

If you stored the key/secret to the credential files, we can use the different Serverless commands by designtating the profile at each command:

serverless deploy --aws-profile serverless

We can also export the profile as well as the region to environement variables:

export AWS_PROFILE="serverless" && export AWS_REGION=eu-west-1

Initializing our Project

In the app folder, we need to create a serverless.yml file. This file is needed to configure how our application will behave.

We need also to create our Python function (called handler.py):

In order to do this, let’s execute this command:

serverless create --template aws-python3 --name hello-world

This will create the handler file, the configuration file and the .gitignore file:

.
├── .gitignore
├── handler.py
└── serverless.yml

This is how our serverless.yml file looks like:

provider:
  name: aws
  runtime: python3.6
functions:
  hello:
    handler: handler.hello

This is how the handler.py file looks like:

import json
def hello(event, context):
    body = {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "input": event
    }
response = {
        "statusCode": 200,
        "body": json.dumps(body)
    }
return response
# Use this code if you don't use the http event with the LAMBDA-PROXY
    # integration
    """
    return {
        "message": "Go Serverless v1.0! Your function executed successfully!",
        "event": event
    }
    """

Deploying our Project

Once the template files are created, we have a working AWS Lambda function, we need to deploy it:

export AWS_PROFILE="serverless"
serverless deploy

Note: You need to change the profile name to use your own one.

The deployment output looks like this. You can see that our code is zipped and deployed to a S3 bucket before being deployed to Lambda.

Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (390 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
................
Serverless: Stack update finished...
Service Information
service: hello-world
stage: dev
region: us-east-1
stack: hello-world-dev
api keys:
  None
endpoints:
  None
functions:
  hello: hello-world-dev-hello

The function is now deployed.

Adding Events to our Function

While you do already have a function defined called hello that's linked to a function handler, you currently have no way of triggering that function. That's why we need to add an event to the function defined in serverless.yml . Update it as follows:

We defined a function called hello but we did not define a way to trigger the function, this is when adding an “event” is useful. Edit the serverless.yml file:

provider:
  name: aws
  runtime: python3.6
functions:
hello:
handler: handler.hello
events:
- http:
path: hello
method: get

According to our configuration, the function will be called using the /hello url.

Note: You can choose your own url.

Let’s deploy:

serverless deploy -v
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (390 B)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - hello-world-dev
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - UPDATE_IN_PROGRESS - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - UPDATE_COMPLETE - AWS::Lambda::Function - HelloLambdaFunction
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::RestApi - ApiGatewayRestApi
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHello
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceHello
CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Resource - ApiGatewayResourceHello
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodHelloGet
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodHelloGet
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1534113893559
CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1534113893559
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Deployment - ApiGatewayDeployment1534113893559
CloudFormation - CREATE_COMPLETE - AWS::Lambda::Permission - HelloLambdaPermissionApiGateway
CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - hello-world-dev
CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - hello-world-dev
Serverless: Stack update finished...
Service Information
service: hello-world
stage: dev
region: us-east-1
stack: hello-world-dev
api keys:
None
endpoints:
GET - https://x7o0xwsbkd.execute-api.us-east-1.amazonaws.com/dev/hello
functions:
hello: hello-world-dev-hello
Stack Outputs
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:998335703874:function:hello-world-dev-hello:1
ServiceEndpoint: https://x7o0xwsbkd.execute-api.us-east-1.amazonaws.com/dev
ServerlessDeploymentBucketName: hello-world-dev-serverlessdeploymentbucket-qqgrblrjprhu

As you may see in the deployment logs that the AWS lambda function has a new URL:

<a href="https://x7o0xwsbkd.execute-api.us-east-1.amazonaws.com/dev/hello" data-href="https://x7o0xwsbkd.execute-api.us-east-1.amazonaws.com/dev/hello" rel="nofollow noopener noopener" target="_blank">https://x7o0xwsbkd.execute-api.us-east-1.amazonaws.com/dev/hello</a>

We can test our function using the browser, tools like Postman, the CLI or Serverless invoke command.

Using CURL:

curl -X GET <a href="https://x7o0xwsbkd.execute-api.us-east-1.amazonaws.com/dev/hello" data-href="https://x7o0xwsbkd.execute-api.us-east-1.amazonaws.com/dev/hello" rel="nofollow noopener noopener noopener" target="_blank">https://x7o0xwsbkd.execute-api.us-east-1.amazonaws.com/dev/hello</a>

Output:

{
   "message":"Go Serverless v1.0! Your function executed successfully!",
   "input":{
      "resource":"/hello",
      "path":"/hello",
      "httpMethod":"GET",
      "headers":{
         "Accept":"*/*",
         "CloudFront-Forwarded-Proto":"https",
         "CloudFront-Is-Desktop-Viewer":"true",
         "CloudFront-Is-Mobile-Viewer":"false",
         "CloudFront-Is-SmartTV-Viewer":"false",
         "CloudFront-Is-Tablet-Viewer":"false",
         "CloudFront-Viewer-Country":"FR",
         "Host":"x7o0xwsbkd.execute-api.us-east-1.amazonaws.com",
         "User-Agent":"curl/7.47.0",
         "Via":"1.1 xxx.cloudfront.net (CloudFront)",
         "X-Amz-Cf-Id":"",
         "X-Amzn-Trace-Id":"Root=1-5b70bbe0-f318b862a8dfdb1e38fc337e",
         "X-Forwarded-For":"",
         "X-Forwarded-Port":"443",
         "X-Forwarded-Proto":"https"
      },
      "queryStringParameters":null,
      "pathParameters":null,
      "stageVariables":null,
      "requestContext":{
         "resourceId":"bsk6aq",
         "resourcePath":"/hello",
         "httpMethod":"GET",
         "extendedRequestId":"LiJLDHe3oAMF7kQ=",
         "requestTime":"12/Aug/2018:22:59:44 +0000",
         "path":"/dev/hello",
         "accountId":"xxx",
         "protocol":"HTTP/1.1",
         "stage":"dev",
         "requestTimeEpoch":1534114784336,
         "requestId":"6727b590-9e83-11e8-a9cc-61641c6c77ac",
         "identity":{
            "cognitoIdentityPoolId":null,
            "accountId":null,
            "cognitoIdentityId":null,
            "caller":null,
            "sourceIp":"",
            "accessKey":null,
            "cognitoAuthenticationType":null,
            "cognitoAuthenticationProvider":null,
            "userArn":null,
            "userAgent":"curl/7.47.0",
            "user":null
         },
         "apiId":"x7o0xwsbkd"
      },
      "body":null,
      "isBase64Encoded":false
   }
}

Using serverless invoke:

sls invoke -f hello

Output:

{
    "statusCode": 200,
    "body": "{\"message\": \"Go Serverless v1.0! Your function executed successfully!\", \"input\": {}}"
}

Tailing Logs

Sometimes, you need to see the execution or the deployment logs. This is the command to tail the logs:

sls logs -f hello --tail

Deleting the Function

Using sls remove command, we can delete the deployed service from AWS Lambda.

serverless remove

We can add other options like:

  • --stage or -s The name of the stage in service.
  • --region or -r The name of the region in stage.
  • --verbose or -v Shows all stack events during deployment.

Note: Removing a service will also remove the S3 bucket.

Connect Deeper

We have seen how to deploy our first Lambda function using the Serverless Framework. Stay in touch as the upcoming posts will go more in depth.

I am creating a series of blog posts to help you develop, deploy and run (mostly) Python applications on AWS Lambda using Serverless Framwork.

You can find my other articles about the same topic but using other frameworks like Creating a Serverless Uptime Monitor & Getting Alerted by SMS — Lambda, Zappa & Python or Creating a Serverless Python API Using AWS Lambda & Chalice

Don’t forget to subscribe to Shipped: An Independent Newsletter Focused On Serverless, Containers, FaaS & Other Interesting Stuff .

JRNBFn6.png!web

You may be interested in learning more about Lambda and other AWS service, so please take a look at Practical AWS, a training concerned with the actual use of AWS rather than with theory & ideas .

77z22mV.jpg!web
uiiIRnB.png!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK