This is your whole application. All code in scala. Infrastructure as terraform code. To start a new project, simply download or clone this example.
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.
- sbt
- yarn
- node (>= 10.13.0)
- aws-cli
- terraform (>= 1.3.0): https://www.terraform.io/downloads.html
- direnv
The provided shell.nix
contains these dependencies, so if you are using nix
, just run a nix-shell
.
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
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
Webpack configuration: lambda/webpack.config.dev.js
, lambda/webpack.config.prod.js
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.
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"
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.
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
.
SDK library to communicate with the infrastructure in your code:
- Fun SDK Scala: sdk-scala
Terraform module for the corresponding AWS infrastructure:
- Fun Terraform Module: terraform-aws-fun
See local development module for mocking the AWS infrastructure locally:
- Fun Local Environment: local-env