Skip to content
/ example Public template

Example for fun-stack, a Serverless Full-Stack Scala Framework

Notifications You must be signed in to change notification settings

fun-stack/example

Repository files navigation

Example

This is your whole application. All code in scala. Infrastructure as terraform code. To start a new project, simply download or clone this example.

Overview

Three scala projects:

  • lambda/: backend code deployed as lambda functions behind api gateway
  • webapp/: frontend code deployed to s3 bucket behind cloudfront
  • api/: shared code between lambda and webapp

Terraform deployment:

  • terraform/: terraform code to deploy backend and frontend to AWS.

Requirements

The provided shell.nix contains these dependencies, so if you are using nix, just run a nix-shell.

Development

Watch and compile the application. Runs a webserver for the website, http and websocket servers for your backend lambdas, and a local auth server:

# assuming direnv sourced .envrc:
dev

You will see your locally running full-stack app at http://localhost:12345.

Changing any source file will automatically recompile and hot-reload the website and backends.

To know more about the details, have a look at scripts/dev.

If you just want to develop on your frontend without any backend:

sbt devf

Infos about webapp

Webpack configuration: webapp/webpack.config.dev.js, webapp/webpack.config.prod.js

Postcss configuration (picked up by webpack): webapp/postcss.config.js

Tailwind configuration (picked up by postcss): webapp/tailwind.config.js

Template for index.html and css (picked up by webpack): webapp/src/main/html/index.html, webapp/src/main/css/

Static assets folder (picked up by webpack): webapp/assets/

Local development configuration for your webapp: webapp/local/app_config.js

Infos about lambda

Webpack configuration: lambda/webpack.config.dev.js, lambda/webpack.config.prod.js

Deployment

Initial steps

You have to do these steps only once.

Create an s3-bucket and dynamodb table for the terraform state (generates a terraform/terraform.tf file):

# export AWS_PROFILE=<my-profile>
./terraform/initial_setup.sh
# git add terraform/terraform.tf

Be aware that the setup.sh script uses region eu-central-1. Edit the created terraform.tf with the region of your account if needed. Also make sure the default_tags and local.tags suit your needs which makes searching and aggregating over resources much easier.

If you have a custom domain

Set your domain in terraform/fun.tf.

Create a hosted zone in AWS for this custom domain. Either just register your domain in AWS directly - then you do not need to do anything else here. Or create a hosted zone in AWS for your already owned domain:

aws route53 create-hosted-zone --name "example.com" --caller-reference $(date +%s)

For your already owned domain, you need point your domain registrar to the nameservers of this hosted zone. You need to do this where you bought the domain. Here is a command to print the nameserver IPs of the hosted zone again:

HOSTED_ZONE_ID=$(aws route53 list-hosted-zones-by-name --dns-name "example.com" | jq -r ".HostedZones[0].Id")
aws route53 get-hosted-zone --id $HOSTED_ZONE_ID | jq ".DelegationSet.NameServers"

Deploy steps

First build the application:

sbt prod

Then go into the terraform directory. Set your AWS_PROFILE. And run terraform:

export AWS_PROFILE=...
cd terraform
terraform init -upgrade -reconfigure
terraform apply

Then the app is available under https://example.com. Without a custom domain, you can see the endpoint in the outputs of the apply command.

Environments

If you want to try something out without interrupting others, you can make your own terraform workspace and setup your own independent deployment:

terraform workspace new <my-workspace>
terraform workspace switch <my-workspace>
# run terraform as usual

If you are not on the default terraform workspace, the app is available under: https://<my-workspace>.env.example.com.

Links

SDK library to communicate with the infrastructure in your code:

Terraform module for the corresponding AWS infrastructure:

See local development module for mocking the AWS infrastructure locally: