Lesson 18-Serverless Development Introduction

Setting Up a Serverless Development Environment

1. Cloud Service Account Configuration

Mainstream Cloud Provider Account Setup

# AWS account configuration example
aws configure
# Enter AWS Access Key ID, Secret Access Key, default region, and output format

Multi-Account Management Solution

# Use AWS Profiles to manage multiple accounts
aws configure --profile dev
aws configure --profile prod

Permission Policy Configuration

// Least privilege IAM policy example (allows Lambda deployment only)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "lambda:CreateFunction",
        "lambda:UpdateFunctionCode",
        "lambda:UpdateFunctionConfiguration"
      ],
      "Resource": "arn:aws:lambda:*:*:function/*"
    },
    {
      "Effect": "Allow",
      "Action": "logs:CreateLogGroup",
      "Resource": "arn:aws:logs:*:*:*"
    }
  ]
}

2. Serverless Framework Installation

Global Installation

# Install Serverless Framework using npm
npm install -g serverless

# Verify installation
serverless --version

Configure Cloud Provider Plugins

# AWS plugin (included by default)
serverless create --template aws-nodejs

# Azure plugin
npm install --save-dev serverless-azure-functions

# Google Cloud plugin
npm install --save-dev serverless-google-cloudfunctions

Configuration File (serverless.yml)

service: my-first-service

provider:
  name: aws
  runtime: nodejs18.x
  region: us-east-1
  profile: dev # Use configured AWS Profile

functions:
  helloWorld:
    handler: handler.helloWorld

3. Local Development Tools

AWS SAM CLI Installation

# Install SAM CLI
brew tap aws/tap
brew install aws-sam-cli

# Verify installation
sam --version

LocalStack Installation (Simulates AWS Services)

# Install LocalStack using Docker
docker run --rm -it -p 4566:4566 -p 4571:4571 localstack/localstack

# Configure Serverless to use LocalStack
provider:
  name: aws
  runtime: nodejs18.x
  endpointType: http
  httpApi:
    endpoint: http://localhost:4566

VS Code Development Configuration

// .vscode/settings.json
{
  "serverless.framework": "aws",
  "serverless.aliases": {
    "dev": "profile:dev",
    "prod": "profile:prod"
  },
  "terminal.integrated.env.linux": {
    "AWS_PROFILE": "dev"
  }
}

Creating Your First Serverless Function

1. Creating and Deploying a Function

Creating a Function

# Create a new service using Serverless
serverless create --template aws-nodejs --path my-service

# Directory structure
my-service/
├── handler.js       # Function code
├── serverless.yml   # Configuration file
└── package.json     # Dependency management

Deploying a Function

# Deploy the entire service
serverless deploy

# Deploy a single function
serverless deploy function --function helloWorld

Deployment Result Example

Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service .zip file to S3 (1.23 MB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
Serverless: Stack update finished...
Service Information
service: my-first-service
stage: dev
region: us-east-1
stack: my-first-service-dev
resources: 7
api keys:
  None
endpoints:
  GET - https://abc123.execute-api.us-east-1.amazonaws.com/dev/hello
functions:
  helloWorld: my-first-service-dev-helloWorld
layers:
  None

2. Configuring Triggers

HTTP Trigger Configuration

functions:
  helloWorld:
    handler: handler.helloWorld
    events:
      - http:
          path: hello
          method: get
          cors: true
          authorizer: aws_iam

Scheduled Trigger Configuration

functions:
  scheduledJob:
    handler: handler.scheduledJob
    events:
      - schedule: rate(1 hour) # Execute every hour
        # Or use Cron expression
        # - schedule: cron(0 12 * * ? *) # Daily at 12 PM

Multiple Triggers Example

functions:
  multiTrigger:
    handler: handler.multiTrigger
    events:
      - http:
          path: trigger
          method: post
      - sns: arn:aws:sns:us-east-1:123456789012:MyTopic
      - s3:
          bucket: my-bucket
          event: s3:ObjectCreated:*
          existing: true

3. Function Logging and Debugging

Viewing Logs

# View logs in real-time
serverless logs -f helloWorld --tail

# View logs for a specific time period
serverless logs -f helloWorld --startTime "1 hour ago"

Log Level Configuration

provider:
  logging:
    http: true # Log HTTP requests
    level: INFO # Log level (DEBUG, INFO, WARN, ERROR)

Debugging Techniques

  1. Local Event Simulation:
# Test with sam local
sam local invoke "HelloWorldFunction" -e event.json
  1. Remote Debugging Configuration:
functions:
  debugFunction:
    handler: handler.debugFunction
    environment:
      NODE_OPTIONS: '--inspect=0.0.0.0:9229' # Enable remote debugging
  1. X-Ray Tracing Integration:
provider:
  tracing:
    apiGateway: true
    lambda: true

Integrating Serverless with Frontend

1. Frontend Calling Serverless APIs

API Gateway Integration

// Frontend call example (React)
import axios from 'axios';

async function fetchData() {
  try {
    const response = await axios.get('https://abc123.execute-api.us-east-1.amazonaws.com/dev/hello');
    console.log(response.data);
  } catch (error) {
    console.error('API call failed:', error);
  }
}

Custom Domain Configuration

provider:
  apiGateway:
    restApiId: abc12345678
    restApiRootResourceId: /myresource
    restApiResources:
      /myresource: /myresource

custom:
  customDomain:
    domainName: api.myapp.com
    basePath: ''
    stage: ${self:provider.stage}
    createRoute53Record: true

2. Static Resource Hosting

S3 + CloudFront Configuration

resources:
  Resources:
    WebsiteBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: ${self:service}-${self:provider.stage}-static
        AccessControl: PublicRead
        WebsiteConfiguration:
          IndexDocument: index.html
          ErrorDocument: index.html

    CloudFrontDistribution:
      Type: AWS::CloudFront::Distribution
      Properties:
        DistributionConfig:
          Origins:
            - DomainName: ${self:resources.Resources.WebsiteBucket.DomainName}
              Id: S3Origin
              S3OriginConfig: {}
          Enabled: true
          DefaultCacheBehavior:
            TargetOriginId: S3Origin
            ViewerProtocolPolicy: redirect-to-https
          ViewerCertificate:
            CloudFrontDefaultCertificate: true

Deploying Static Resources

# Upload static files using aws-cli
aws s3 sync ./public s3://${self:service}-${self:provider.stage}-static --delete

3. Frontend Authentication and Authorization

Cognito User Pool Integration

provider:
  cognito:
    userPoolId: us-east-1_abcdefg
    userPoolClientId: abc123def456ghi789jkl

functions:
  authHandler:
    handler: handler.authHandler
    events:
      - http:
          path: login
          method: post
          authorizer: aws_iam

Frontend Authentication Flow

// Authentication using AWS Amplify
import { Auth } from 'aws-amplify';

async function signIn(username, password) {
  try {
    const user = await Auth.signIn(username, password);
    console.log('Login successful:', user);
    return user;
  } catch (error) {
    console.error('Login failed:', error);
    throw error;
  }
}

// Retrieve JWT token
const token = (await Auth.currentSession()).getIdToken().getJwtToken();

API Gateway Authorization Configuration

functions:
  protectedFunction:
    handler: handler.protectedFunction
    events:
      - http:
          path: protected
          method: get
          authorizer:
            name: myAuthorizer
            arn: arn:aws:cognito-idp:us-east-1:123456789012:userpool/us-east-1_abcdefg

Advanced Practice Recommendations

  1. Environment Isolation Strategy:
provider:
  stage: ${opt:stage, 'dev'} # Specify environment via command-line parameters
  environment:
    STAGE: ${self:provider.stage}
    DB_URL: ${env:DB_URL_${self:provider.stage}}
  1. Performance Optimization Tips:
    • Use Provisioned Concurrency for pre-warmed instances
    • Set appropriate memory and timeout values (higher memory often increases CPU allocation)
    • Leverage Lambda Layers for shared dependencies
  2. Security Best Practices:
    • Configure IAM roles with least privilege principles
    • Use AWS Secrets Manager for sensitive information
    • Enable VPC for isolating sensitive resources
  3. CI/CD Pipeline Example:
# GitHub Actions example
name: Deploy Serverless Application

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-node@v2
      - run: npm install
      - run: serverless deploy --stage prod --aws-profile production
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

By following these steps, you can set up a complete Serverless development environment, create and deploy your first function, and achieve efficient integration with frontend applications. Start with simple functions, gradually expand to complex scenarios, and continuously optimize performance and security.

Share your love