Skip to content

Latest commit

 

History

History
130 lines (94 loc) · 6.59 KB

serverless-guide.md

File metadata and controls

130 lines (94 loc) · 6.59 KB

Serverless: Getting Started

Serverless backends like AWS Lambda allow us to write and run code without thinking about what server it is going to run on. Specifically, these technologies allow us to automatically scale based on traffic and only pay for as much as we use. It's great for applications where traffic is inconsistent.

💡 We use "lower-case" serverless – the architecture, not the name-brand framework. (Why?)

Step 1: Creating our Function

We manage our serverless infrastructure with Terraform. To start, use the lambda_function module to provision a new function. This will create a new function with the given name. It will also create a log group, execution role, deployment bucket, and limited deployment credentials.

module "app" {
  source = "../components/lambda_function"

  name    = "hello-serverless"
  runtime = "nodejs12.x"
}

After you run make apply, you should see the function on the AWS Console:

AWS Lambda GUI

We haven't configured the function to accept HTTP requests yet (and not all Serverless functions have to). We can check that everything works by executing this function using the AWS CLI:

$ aws lambda invoke --function-name=hello-serverless /dev/stdout

{"statusCode":200,"headers":{"Content-Type":"text/html; charset=utf-8"},"body":"<p>Hello world!</p>"}{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}

We're off to a great start! 🚀

Step 2: Add HTTP Endpoints (optional)

Often, we'll want our functions to be accessible via the internet. To do so, we can use the api_gateway_proxy module:

module "gateway" {
  source = "../components/api_gateway_proxy"

  name                = "hello-serverless"
  environment         = "development"
  function_arn        = "${module.app.arn}"
  function_invoke_arn = "${module.app.invoke_arn}"
}

If we apply that change and return to our Lambda dashboard, we'll see it now has a "API Gateway" trigger. Click on it to see the URL that's been automatically provisioned for this application:

Lambda dashboard with API Gateway trigger

If we visit that URL, anyone can now execute our "hello world" Lambda function via the web!

Hello World function over the web

Bonus: Add a Custom Domain

To use a custom domain, just set the domain variable on the gateway:

module "gateway" {
  # ...
  domain = "hello-serverless.dosomething.org"
}

This will attach the custom domain to our API Gateway, and (if it's a DoSomething.org subdomain) automatically provision a SSL Certificate using Amazon Certificate Manager. If you're using a different top-level domain, you'll need to manually request & validate a certificate.

Once you've attached the custom domain, visit API Gateway's Custom Domain Names panel to find out what CNAME to point the DNS record at. Ask someone in #dev-infrastructure to attach it to the domain in our DNSMadeEasy account. You may have to wait up to 40 minutes for the certificate and CloudFront distribution to finish provisioning:

screen shot 2019-02-06 at 5 10 58 pm

Your patience will be rewarded with a fancy new domain!

screen shot 2019-02-06 at 5 54 04 pm

Step 3: Deploying Code

In rare cases, you may want more than the default "hello world" app can provide. Luckily, deploying code is a breeze.

We deploy our serverless applications using CircleCI and our dosomething/lambda helper orb. If you haven't already, add a .circleci/config.yml file to your application's repository. You can use the template below to start, making sure to replace hello-serverless in the deploy step with the name of your Lambda function:

version: 2.1

orbs:
  lambda: dosomething/lambda@0.0.3

jobs:
  # Install dependencies, run tests, and compile for Lambda.
  build:
    docker:
      - image: circleci/node:8.10
    steps:
      - checkout
      - restore_cache:
          keys:
          - v1-dependencies-{{ checksum "package.json" }}
          - v1-dependencies-
      - run: npm install
      - save_cache:
          paths:
            - node_modules
          key: v1-dependencies-{{ checksum "package.json" }}
      - lambda/store

# Configure workflows & scheduled jobs:
workflows:
  version: 2
  build-deploy:
    jobs:
      - build
      - lambda/deploy:
          name: deploy
          app: hello-serverless
          requires:
            - build
          filters:
            branches:
              only: main

After adding this file to your application's repository, add the app as a "project". Your first build may fail due to missing credentials - that's okay! Head to the project's "Build Settings" page and import environment variables from an existing serverless project, such as dosomething/graphql.

Now, any commits to the default branch on this repository will automatically deploy our Lambda function!

screen shot 2019-02-06 at 6 00 59 pm