Skip to content

Commit

Permalink
feat(functions): add node terraform example (#91)
Browse files Browse the repository at this point in the history
* feat: add node terraform example

* fix: add to main README

* fix: typo in worthwhile

* docs: grammar

Co-authored-by: Emilie BOUIN <[email protected]>

---------

Co-authored-by: Emilie BOUIN <[email protected]>
  • Loading branch information
cyclimse and Bemilie authored Oct 9, 2024
1 parent c21f803 commit 87c9569
Show file tree
Hide file tree
Showing 8 changed files with 1,018 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Table of Contents:
- [Examples](#examples)
- [🚀 Functions](#-functions)
- [📦 Containers](#-containers)
- [⚙️ Jobs](#-jobs)
- [⚙️ Jobs](#-jobs)
- [💬 Messaging and Queueing](#-messaging-and-queueing)
- [💜 Projects](#-projects)
- [Contributing](#contributing)
Expand All @@ -41,6 +41,7 @@ Table of Contents:
| **[Go MultiPart Upload to S3](functions/go-upload-file-s3-multipart)** <br/> A function to upload file from form-data to S3. | go120 | [Serverless Framework] |
| **[Image Transform](functions/image-transform-node/README.md)** <br/> A function that resizes images from an S3 bucket. | node22 | [Serverless Framework] |
| **[Image Transform with triggers](functions/trigger-image-transform-node/README.md)** <br/> A function that resizes images from an S3 bucket and use SQS triggers to smooth traffic. | node20 | [Serverless Framework] |
| **[Node Terraform](functions/node-terraform/README.md)** <br/> A simple example of deploying a Node Serverless function using Terraform. | node22 | [Terraform] |
| **[Node MultiPart Upload to S3](functions/node-upload-file-s3-multipart/README.md)** <br/> A function to upload file from form-data to S3. | node19 | [Serverless Framework] |
| **[PHP write to S3](functions/php-s3/README.md)** <br/> A PHP function that connects to, and writes to an S3 bucket. | php82 | [Terraform] |
| **[PostgeSQL Node](functions/postgre-sql-node/README.md)** <br/> A Node function to connect and interact with PostgreSQL database. | node18 | [Serverless Framework] |
Expand Down
2 changes: 2 additions & 0 deletions functions/node-terraform/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Artifacts
files/
40 changes: 40 additions & 0 deletions functions/node-terraform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Node Terraform

An example deploying a Node Serverless function using Terraform. The function is a simple `rss` feed that filters the content of a source feed and returns the filtered content.

## Requirements

- [Node.js](https://nodejs.org/en/download/)
- [Terraform](https://learn.hashicorp.com/terraform/getting-started/install.html)
- A configured Scaleway Profile. You can find more information [here](https://www.scaleway.com/en/docs/developer-tools/terraform/reference-content/scaleway-configuration-file/#how-to-set-up-the-configuration-file)

## Usage

Run the function locally:

```bash
cd function
npm install --include=dev
npm start
```

In another terminal, you can the following command to test the function:

```bash
curl http://localhost:8081
```

Deploy the function using Terraform:

```bash
terraform init
terraform apply
```

The function is a `rss` feed that can be accessed via a RSS reader. The URL of the feed is displayed in the output of the Terraform apply command.

## Cleanup

```bash
terraform destroy
```
63 changes: 63 additions & 0 deletions functions/node-terraform/function/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import Parser from "rss-parser";
import RSS from "rss";

const parser = new Parser({
headers: { "User-Agent": "Scaleway Serverless Examples" },
});
const SOURCE_FEED_URL = process.env.SOURCE_FEED_URL || "https://lobste.rs/rss";
const WORTHWHILE_TOPICS = process.env.WORTHWHILE_TOPICS ||
"nixos, nix, serverless, terraform";

const feed = new RSS({
title: `Worthwhile items from ${SOURCE_FEED_URL}`,
description: `All about ${WORTHWHILE_TOPICS}`,
language: "en",
ttl: "60",
});

// This is a simple function that given an RSS feed,
// filters out the items that contain any of the topics in the WORTHWHILE_TOPICS environment variable.
// It then exposes a RSS feed on its own, with the filtered items.
async function handler(event, _context, _cb) {
const userAgent = event.headers["User-Agent"];
const ip = event.headers["X-Forwarded-For"].split(",")[0];
console.log("Got request from %s with user agent %s", ip, userAgent);

const topics = WORTHWHILE_TOPICS.split(",").map((t) => t.trim());

const sourceFeed = await parser.parseURL(SOURCE_FEED_URL);
console.log("Parsing feed: %s", feed.title);

const worthwhileItems = sourceFeed.items.filter((item) => {
// Filter out items that don't contain any of the topics
return topics.some((topic) => item.title.toLowerCase().includes(topic));
});

console.log("Found %d worthwhile items", worthwhileItems.length);

worthwhileItems.forEach((item) => {
// Shamelessly repost the items
feed.item({
title: item.title,
description: item.content,
url: item.link,
date: item.pubDate,
});
});

return {
statusCode: 200,
headers: {
"Content-Type": "application/xml",
},
body: feed.xml(),
};
}

export { handler };

if (process.env.NODE_ENV === "development") {
import("@scaleway/serverless-functions").then((nodeOffline) => {
nodeOffline.serveHandler(handler, 8081);
});
}
Loading

0 comments on commit 87c9569

Please sign in to comment.