Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(functions): add node terraform example #91

Merged
merged 4 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading