API Gateways and Lambda

In this tutorial, we’ll use Pulumi to create a serverless app that serves static content, in addition to dynamic routes in AWS Lambda. We’ll do this with 5 lines of JavaScript, a few lines of configuration, and whatever static content we wish to serve (in this case, a simple HTML page and a favicon). After seeing this in action, we’ll build on these basic concepts to explore additional containers, serverless, and infrastructure tutorials.


  1. Install Pulumi
  2. Configure AWS credentials

Initialize the project

Let’s use the Pulumi CLI to initialize a new project:

$ mkdir ahoy-pulumi && cd ahoy-pulumi
$ pulumi new hello-aws-javascript

You can accept the defaults for this command. For instance, you can change the AWS region to us-west-2.

Run Pulumi new

After some dependency installations from NPM, you’ll see a few files have been generated from this initialization process.

View files

Let’s look at some of those.

  • Pulumi.yaml defines the project.
  • Pulumi.ahoy-pulumi-dev.yaml is the configuration file for the stack we initialized.
  • www contains our sample static content.
  • The key file for defining our stack resources index.js so let’s examine that.

Define stack resources

Normally, we’d write some code to define resources for our cloud stack, but in the quickstart this work is done for us. This is the content of index.js:

const pulumi = require("@pulumi/pulumi");
const aws = require("@pulumi/aws");
const awsx = require("@pulumi/awsx");

// Create a public HTTP endpoint (using AWS APIGateway)
const endpoint = new awsx.apigateway.API("hello", {
    routes: [
        // Serve static files from the `www` folder (using AWS S3)
            path: "/",
            localPath: "www",

        // Serve a simple REST API on `GET /name` (using AWS Lambda)
            path: "/source",
            method: "GET",
            eventHandler: (req, ctx, cb) => {
                cb(undefined, {
                    statusCode: 200,
                    body: Buffer.from(JSON.stringify({ name: "AWS" }), "utf8").toString("base64"),
                    isBase64Encoded: true,
                    headers: { "content-type": "application/json" },

// Export the public URL for the HTTP service
exports.url = endpoint.url;

See the reference documentation for details on the APIs we’re using.

Deploy the stack

The stack is ready to deploy, which is done as follows:

$ pulumi up

This command instructs Pulumi to determine the resources needed to create the stack. First, a preview is shown of the changes that will be made:

Stack preview

Choosing yes will create resources in AWS. This may take a minute or two.

Stack update

Since there was a stack export (via exports.url in the code), this is printed in the output of pulumi up. We can easily curl this URL via pulumi stack output:

$ curl $(pulumi stack output url)

For a more interesting view that shows the result of calling a Lambda function, open the page in a browser:

Stack page in browser

Manage the stack

Our output also contained a permalink to the Pulumi dashboard. We can review the stack in the UI, and examine logs and resource usage, along with inviting friends and co-workers to collaborate on stacks.

Tear Down

To destroy resources, run the following:

$ pulumi destroy

Once confirmed, Pulumi will remove all of the resources you’ve created. The stack itself is preserved in the Pulumi dashboard and is ready to go again as needed.


In this example we’ve seen:

  • How Pulumi makes the definition of cloud resources and stacks a highly productive, code-driven activity.
  • How the Pulumi CLI can initialize, configure, deploy, and manage cloud stacks.
  • How the Pulumi dashboard can log, monitor, and manage information about a cloud stack.

Next Steps

From here, you can dive deeper: