Skip to content

Commit 2b46245

Browse files
authored
feat(jobs): add Serverless Jobs Terraform example (#75)
* Add Jobs Terraform example * Add link in main README * Add CRON schedule
1 parent 57ead75 commit 2b46245

File tree

10 files changed

+153
-3
lines changed

10 files changed

+153
-3
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,17 @@ Table of Contents:
6666
| **[Function Handler Java](containers/function-handler-java/README.md)** <br/> A Java function handler deployed on CaaS. | Java | [Serverless Framework] |
6767
| **[NGINX CORS Private](containers/nginx-cors-private-python/README.md)** <br/> An NGINX proxy to allow CORS requests to a private container. | Python Flask | [Terraform] |
6868
| **[NGINX hello world](containers/nginx-hello-world/README.md)** <br/> A minimal example running the base NGINX image in a serverless container. | N/A | [Serverless Framework] |
69-
| **[Python hello world](containers/python-hello-world/README.md)** <br/> A minimal example running a Flask HTTP server in a serverless container. | N/A | [Serverless Framework] |
70-
| **[Python S3 upload](containers/python-s3-upload/README.md)** <br/> A Python + Flask HTTP server that receives file uploads and writes them to S3. | N/A | [Terraform] |
69+
| **[Python hello world](containers/python-hello-world/README.md)** <br/> A minimal example running a Flask HTTP server in a serverless container. | Python | [Serverless Framework] |
70+
| **[Python S3 upload](containers/python-s3-upload/README.md)** <br/> A Python + Flask HTTP server that receives file uploads and writes them to S3. | Python | [Terraform] |
7171
| **[Terraform NGINX hello world](containers/terraform-nginx-hello-world/README.md)** <br/> A minimal example running the base NGINX image in a serverless container deployed with Terraform. | N/A | [Terraform] |
7272
| **[Triggers with Terraform](containers/terraform-triggers/README.md)** <br/> Configuring two SQS triggers, used to trigger two containers, one public, one private. | N/A | [Terraform] |
7373

7474
### ⚙️ Jobs
7575

7676
| Example | Language | Deployment |
7777
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|------------------------|
78-
| **[Serverless MLOps](jobs/ml-ops/README.md)** <br/> An example to run a Serverless Machine Leaning workflow | Python |[Terraform]-[Console]-[CLI]|
78+
| **[Serverless Jobs Hello World](jobs/terraform-hello-world/README.md)** <br/> An example of building a container image and running it as a Serverless Job using Terraform. | N/A |[Terraform]-[Console]|
79+
| **[Serverless MLOps](jobs/ml-ops/README.md)** <br/> An example of running a Serverless Machine Leaning workflow. | Python |[Terraform]-[Console]-[CLI]|
7980

8081
### 💬 Messaging and Queueing
8182

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Serverless Jobs Hello World with Terraform
2+
3+
This example demonstrates how to set up a Scaleway [Serverless Job](https://www.scaleway.com/en/serverless-jobs/) using [Terraform](https://www.terraform.io/).
4+
5+
It builds a custom image locally, pushes this to the Scaleway registry, then creates a job that runs this image on a schedule.
6+
7+
## Requirements
8+
9+
This example assumes you are familiar with how Serverless Jobs work. If needed, you can check [Scaleway's official documentation](https://www.scaleway.com/en/docs/serverless/jobs/quickstart/)
10+
11+
This example uses Terraform. Please set up your local environment as outlined in the docs for the [Scaleway Terraform Provider](https://registry.terraform.io/providers/scaleway/scaleway/latest/docs).
12+
13+
You will also need a Scaleway API key, which can be configured using [Scaleway IAM](https://www.scaleway.com/en/docs/identity-and-access-management/iam/how-to/create-api-keys/). If you are using IAM policies, make sure the key has the permissions: `ServerlessJobsFullAccess`, `ContainerRegistryFullAccess`.
14+
15+
## Setup
16+
17+
Once your environment is set up, you need to export some environment variables to use your API key:
18+
19+
```console
20+
export TF_VAR_access_key=<your api key>
21+
export TF_VAR_secret_key=<your secret key>
22+
export TF_VAR_project_id=<your project ID>
23+
```
24+
25+
From there, you can run the following to set up your job:
26+
27+
```console
28+
cd terraform
29+
30+
terraform init
31+
32+
terraform plan
33+
34+
terraform apply
35+
```
36+
37+
You can then view your Job Definitions in the [Scaleway Console](https://console.scaleway.com/serverless-jobs/jobs).
38+
39+
The Job is set to run on a schedule, once every 5 minutes. Once the next schedule has run, you will see a "Job Run" listed for your Job Definition.
40+
41+
*Note* this job will keep running every 5 minutes, so you need to make sure you delete the job by running:
42+
43+
```console
44+
cd terraform
45+
46+
terraform destroy
47+
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM alpine:3.19
2+
3+
RUN apk add --no-cache --upgrade bash
4+
5+
COPY hello.sh .
6+
7+
CMD ["sh", "hello.sh"]
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash
2+
3+
set -e
4+
5+
echo "-- Job run at $(date) --"
6+
echo "$MESSAGE"
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
resource "scaleway_registry_namespace" "main" {
2+
name = "jobs-tf-hello"
3+
region = var.region
4+
project_id = var.project_id
5+
}
6+
7+
resource "docker_image" "main" {
8+
name = "${scaleway_registry_namespace.main.endpoint}/jobs-hello:${var.image_version}"
9+
build {
10+
context = "${path.cwd}/../image"
11+
}
12+
13+
provisioner "local-exec" {
14+
command = "docker push ${docker_image.main.name}"
15+
}
16+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
resource "scaleway_job_definition" "main" {
2+
name = "hello_jobs"
3+
cpu_limit = 1000
4+
memory_limit = 1024
5+
6+
image_uri = docker_image.main.name
7+
8+
command = "sh hello.sh"
9+
10+
env = {
11+
"MESSAGE" : "Hello from your Job!",
12+
}
13+
14+
cron {
15+
schedule = "*/5 * * * *"
16+
timezone = "Europe/Paris"
17+
}
18+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
output "job_id" {
2+
value = scaleway_job_definition.main.id
3+
}
4+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
provider "scaleway" {
2+
region = var.region
3+
access_key = var.access_key
4+
secret_key = var.secret_key
5+
project_id = var.project_id
6+
}
7+
8+
provider "docker" {
9+
host = "unix:///var/run/docker.sock"
10+
11+
registry_auth {
12+
address = scaleway_registry_namespace.main.endpoint
13+
username = "nologin"
14+
password = var.secret_key
15+
}
16+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
variable "access_key" {
2+
type = string
3+
}
4+
5+
variable "secret_key" {
6+
type = string
7+
}
8+
9+
variable "project_id" {
10+
type = string
11+
}
12+
13+
variable "image_version" {
14+
type = string
15+
default = "0.0.3"
16+
}
17+
18+
variable "region" {
19+
type = string
20+
default = "fr-par"
21+
}
22+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
terraform {
2+
required_providers {
3+
scaleway = {
4+
source = "scaleway/scaleway"
5+
version = ">= 2.38.2"
6+
}
7+
docker = {
8+
source = "kreuzwerker/docker"
9+
version = "3.0.2"
10+
}
11+
}
12+
required_version = ">= 0.13"
13+
}

0 commit comments

Comments
 (0)