Deploying changes to individual Lambdas using Serverless Framework

I have a serverless project that deploys 2 Lambdas in the same stack:

service: example-apis2

  name: aws
  memorySize: 512
  region: us-west-1
    restApiId: ${env:APIGWID} #  API Gateway to add this api to
    restApiRootResourceId: ${env:RESOURCEID}
    handler: index2.handler
      - arn:aws:lambda:us-west-1:[myaccountid]:layer:example-layer:1
      - http:
          path: api2
          method: get
    handler: index3.handler
      - arn:aws:lambda:us-west-1:[myaccountid]:layer:example-layer:1
      - http:
          path: api3
          method: get

After first deploy, if I do

aws lambda get-function --function-name example-apis2-dev-example2 
"LastModified": "2021-10-27T06:30:31.002+0000",


$ aws lambda get-function --function-name example-apis2-dev-example3
"LastModified": "2021-10-27T06:30:31.987+0000",

Now if I make a code change only to the example 3 Lambda and redeploy only that function with:

serverless deploy function -f example-apis2-dev-example3

… example2 has not been modified since the first deploy (same timestamp as the original deploy):

$ aws lambda get-function --function-name example-apis2-dev-example2
"LastModified": "2021-10-27T06:30:31.002+0000",,

and only example3 shows it was updated/redeployed:

$ aws lambda get-function --function-name example-apis2-dev-example3
"LastModified": "2021-10-27T06:33:17.736+0000",

serverless deploy : deploys the whole stack (but if nothing has changed there is no update)

serverless deploy function -f functioname: updates just the code on that one Lambda (and updates in a couple of seconds vs several seconds for updating the whole stack).

This is described in this article here.

Moving a git ‘master’ branch to ‘main’

By default, the git install on my MacOS 11.5 creates new projects with a ‘master’ branch, but GitHub which I push to for my remote projects has been creating new projects with a default branch of ‘main’ for some time now.

To move a master branch to main locally, set it as the default branch and then push to GitHub I use the following steps (taken from multiple places but mainly from this article):

Create a new main branch from master locally:

git branch -m master main

Add remote GitHub repo:

git remote add github https://your-repo-url

Pull remote changes from remote main branch

git pull github main

Set upstream branch to track main

git branch  --set-upstream-to github/main

Push local to github main

git push github main

If you have changes in the new remote project (like a readme) that don’t exist locally yet and you get the error: “fatal: refusing to merge unrelated histories” then pull with the allow unrelated histories option:

git pull github master --allow-unrelated-histories

Now:’git push’ and you should be good.

For my local development these steps are enough for what I need, but if you have a master in your remote repo too and want to delete it there are additional steps in the article linked above.

Deploying multiple Serverless Framework apis to the same AWS API Gateway

By default, each Serverless project you deploy will create a new API Gateway. In most cases this works fine, but for larger projects you may need to split your apis across multiple smaller Serverless projects, each with their own serverless.yml that can be deployed independently.

The Serverless docs describe how to do this here. In each additional Serverless project where you want to add additional apis to an existing API Gateway, you need to specify 2 additional properties in your Serverless.yml, apiGateway and restApiRootResourceId:

  name: aws
    restApiId: xxxxxxxxxx # REST API resource ID. Default is generated by the framework
    restApiRootResourceId: xxxxxxxxxx # Root resource, represent as / path

apiGateway – this is the 11 character id for your API Gateway that you want to add resources to. You can get this from the console and it’s the prefix in your api gw url, e.g.

The id for the root resource is where in your api path structure you want to add your new resource to, either the id of the root / or one of the existing paths beneath the root.

This id value I don’t think is visible in the console, but you can get it a list of all the resources in your API Gateway including the ids of each of the existing resources, with:

aws apigateway get-resources --rest-api-id aaaaaaaaaaa --region us-west-2

It will give a response that looks like:

    "items": [
            "id": "bbbbbb",
            "parentId": "aaaaaaaaaa",
            "pathPart": "example1",
            "path": "/example1",
            "resourceMethods": {
                "GET": {}
            "id": "aaaaaaaaaa",
            "path": "/"

In this example I have a root / with id = aaaaaaaaa and a resource bbbbbb for /example1.

In this case if I pass aaaaaaaaaa as the value for restApiRootResourceId then my new resource will be added to /, or passing bbbbbb it will be added as a resource under /example1

Enabling AWS API Gateway CloudWatch logging

I deployed a new Lamdba with API Gateway, and when I tried turning on the CloudWatch logging for this API Gateway from the console:

… I got this error that I haven’t seen before:

Turns out per the steps on this page, you need to create an IAM role with API Gateway as the Trusted Entity, and attach the managed policy ‘AmazonAPIGatewayPushToCloudWatchLogs’ :

Add the ARN for the role you created to the Settings for the API you are working with here: