How we leveraged Serverless framework to setup IAC for AppSync & Lambda

IaC for AppSync & Lambda? We made it seamless with Serverless Framework.

What is AWS AppSync?

AppSync is a fully managed, scalable API using GraphQL. It can connect to multiple data sources such as DynamoDB, Lambda, and HTTP endpoints etc. Easily Integrates authentication providers AWS Cognito, IAM, and API keys.

Why choose AppSync over self-managed GraphQL

  • Built-in server-side caching for improved performance of the query.

  • Real-time Subscriptions over WebSockets for real-time data updates.

  • Offline data synchronization with AWS Amplify for seamless data integration.

Advantages of using serverless for managing AppSync and Lambda

  • Easily manage serverless Infrastructure as Code with a YAML config file for serverless.yaml

  • Testing the lambda function locally with the serverless dev command.

  • Handles resource provisioning, versioning, and updates automatically.

Creating a simple GraphQL query to get user details with a unique Id step by step

Prerequisites

  • npm package manager

  • AWS CLI

  • Serverless framework account

Install the serverless framework

npm i serverless -g

Install AppSync plugin

npm install serverless-appsync-plugin

Serverless CLI either requires an account or a license key. It is free for developer organizations with less than $2 million annually.

To create an account, run.

serverless login

It will open a tab in browser once completed; it will redirect to CLI. Note the org name when creating it, it will be used later.

To create a project with a starting template, run

serverless

Navigate to AWS / Python / Simple Function with the arrow keys

Use the name of your project. This will create a new directory with the project name

cd into the directory

cd appsync-python

Additionally, create these files for schema.graphql, request.vtl, and response.vtl

mkdir mapping-templates
touch schema.graphql mapping-templates/request.vtl mapping-templates/response.vtl

Now the files should look like this:

appsync-python
├── handler.py
├── mapping-templates
│   ├── request.vtl
│   └── response.vtl
├── README.md
├── schema.graphql
└── serverless.yml

Now we will write logic which returns name, favMovie using their unique id in handler.py and handles errors when user Id is not found

import json

def getUserById(event, context):
    users = [
        {"id": 1, "name": "Alice", "favMovie": "Inception"},
        {"id": 2, "name": "Bob", "favMovie": "The Matrix"},
        {"id": 3, "name": "Charlie", "favMovie": "Interstellar"}
    ]
    user_id = event.get("id")
    for user in users:
        if user["id"] == user_id:
            return user
    # Return error structure if user not found
    return {"error": f"User with id {user_id} not found"}

request.vtl This transforms GraphQL query to a lambda understandable structure

{
  "version": "2017-02-28",
  "operation": "Invoke",
  "payload": {
    "id": $ctx.args.id
  }
}

response.vtl It changes Python result to GraphQL query structure and handles errors

#if($context.info.fieldName == "getUserById")
#if($context.result.error)
  $utils.error($context.result.error, "NotFound")
#else
  $utils.toJson($context.result)
#end
#end

schema.graphql is used to define a schema in GraphQL. It contains type User and how it should be queried with type Query

type Query {
  getUserById(id: Int!): User
}

type User {
  id: Int
  name: String
  favMovie: String
}

schema {
  query: Query
}

serverless.yaml Here lies all the configuration for running AppSync & Lambda

# "service" is the name of this project. This will also be added to your AWS resource names.
service: appsync-python

#enter the name of the org when creating serverless account
org: "testorg1010"

frameworkVersion: '4'

plugins:
  - serverless-appsync-plugin

appSync:
  name: appsync-python-api
  schema: schema.graphql

provider:
  name: aws
  runtime: python3.12

#this will get the function getUserById from handler.py
functions:
  getUserByIdLambda:
    handler: handler.getUserById

#Creates datasource as lambda
dataSources:
    GetUserByIdLambda:
      type: AWS_LAMBDA
      description: "GetUserById Lambda function"
      config:
        functionName: getUserByIdLambda

#resolver points to which datasource should be used in use of query getuserbyid
#In this case GetUserByIdLambda is resolved
  resolvers:
    Query.getUserById:
      dataSource: GetUserByIdLambda
      kind: UNIT
      request: mapping-templates/request.vtl
      response: mapping-templates/response.vtl
      
  authentication:
    type: API_KEY
  apiKeys:
    - name: mykey
      expireAfter: 1M

Testing Query:

The query can be tested by going to AWS Console -> AppSync -> click on appsync-python-api -> click queries on the sidebar. Run this query to validate

query {
  getUserById(id: 2) {
    id
    name
    favMovie
  }
}

This means your AppSync and Lambda are working successfully

Conclusion

Using the Serverless Framework made it much easier for us to set up and manage our AWS AppSync API and Lambda functions as code. It helped us automate deployments, keep our configurations clean, and manage different environments without much overhead.

Unlock the Full Potential of Your Cloud Infrastructure

Learn Why Adopting the AWS Well-Architected Framework Is a Game-Changer for Your Architecture

EzyInfra.dev – Expert DevOps & Infrastructure consulting! We help you set up, optimize, and manage cloud (AWS, GCP) and Kubernetes infrastructure—efficiently and cost-effectively. Need a strategy? Get a free consultation now!

Share this post

Want to discuss about DevOps practices, Infrastructure Audits or Free consulting for your AWS Cloud?

Prasanna would be glad to jump into a call
Loading...