Oct 27, 20265 min read

How to Set Up AWS for a Side Project

A practical AWS setup for a small TypeScript project: a separate account, a budget alert, and the app itself with an API, a bucket and a nightly job, compared across Encore, Lightsail and Lambda.

AWS is a reasonable home for a side project that might grow, but the first hour decides whether it stays cheap and tidy. The usual problems are a personal account mixed with work, no budget alert, long-lived access keys on a laptop and a pile of console-created resources nobody remembers.

This guide covers the account setup first and then deploys a small TypeScript link shortener with an API, an S3 bucket and a nightly export job, using Encore, Lightsail and Lambda.

What you need to decide:

  • Which account the project lives in and who can sign in.
  • What spend should trigger an alert.
  • How the app's resources are created and later deleted.
  • How much server management you want to do.

Account setup first

Create the project's account inside AWS Organizations, so its bill and resources stay separate and closing it later removes everything. Turn on MFA for the root user, then sign in through IAM Identity Center rather than creating IAM users with access keys.

Add a monthly cost budget with email alerts before deploying anything:

aws budgets create-budget --account-id "$ACCOUNT_ID" \ --budget '{"BudgetName":"side-project","BudgetLimit":{"Amount":"20","Unit":"USD"},"TimeUnit":"MONTHLY","BudgetType":"COST"}' \ --notifications-with-subscribers '[{"Notification":{"NotificationType":"ACTUAL","ComparisonOperator":"GREATER_THAN","Threshold":50},"Subscribers":[{"SubscriptionType":"EMAIL","Address":"you@example.com"}]}]'

AWS Budgets alerts you but does not stop resources, so the alert is a prompt to look, not a cap. Check which services fall under the AWS Free Tier for new accounts before choosing instance sizes.

Side project deploy options at a glance

CapabilityEncoreLightsailLambda and API Gateway
What you manageTypeScript codeA Linux serverFunctions, API, roles
Bucket and cronDeclared in codeSet up separatelyS3 and EventBridge you configure
Local developmentencore run with local bucketYour own setupEmulators or a dev stage
Pricing shapeAWS resources in your accountFixed monthly bundlePer request

Encore: the app and its AWS resources from one codebase

Encore

Encore combines the API, bucket and cron job declared in your TypeScript code with a local environment and deploys them to your own AWS account.

A cron job calls a nightly export that writes the day's CSV to a bucket, so a second run overwrites the same file:

import { api } from "encore.dev/api"; import { CronJob } from "encore.dev/cron"; import { Bucket } from "encore.dev/storage/objects"; const links = new Map<string, string>(); // Stand-in for a table. const exports_ = new Bucket("exports", { versioned: false }); export const exportLinks = api({ expose: false }, async () => { const key = `links-${new Date().toISOString().slice(0, 10)}.csv`; const csv = [...links].map(([s, u]) => `${s},${u}`).join("\n"); await exports_.upload(key, Buffer.from(csv), { contentType: "text/csv" }); }); const _ = new CronJob("nightly-export", { schedule: "0 3 * * *", endpoint: exportLinks });

A database can replace the Map, and encore run starts Postgres locally. Cron jobs do not fire locally. Once the AWS account is connected, pushes through the GitHub integration deploy to AWS, and Encore provisions an IAM role for the service.

An agent can test a new bucket locally before the deploy creates it.

Try Encore →

Lightsail

Lightsail gives you a virtual server with a fixed monthly price. A Node.js app runs under a process manager:

aws lightsail create-instances --instance-names links \ --availability-zone eu-central-1a --blueprint-id ubuntu_24_04 --bundle-id nano_3_0 # On the server: sudo apt-get install -y nodejs npm && sudo npm install -g pm2 pm2 start dist/main.js --name links && pm2 save

Good to know

You patch the OS, set up TLS, deploys and backups, and add a Lightsail bucket or S3 separately. A crontab on the server runs the nightly export. The price is easy to predict.

Lambda and API Gateway

Lambda charges per request, which suits a project with little traffic. The handler is a plain function:

import type { APIGatewayProxyHandlerV2 } from "aws-lambda"; export const get: APIGatewayProxyHandlerV2 = async (event) => { const slug = event.pathParameters?.slug; return slug ? { statusCode: 302, headers: { location: `https://example.com/${slug}` } } : { statusCode: 404 }; };

The API, the bucket and the nightly schedule are declared separately, for example in a SAM template:

Transform: AWS::Serverless-2016-10-31 Resources: Exports: Type: AWS::S3::Bucket GetLink: Type: AWS::Serverless::Function Properties: Runtime: nodejs22.x Handler: get.get Events: Api: Type: HttpApi Properties: { Path: /links/{slug}, Method: GET } ExportLinks: Type: AWS::Serverless::Function Properties: Runtime: nodejs22.x Handler: export.handler Policies: - S3WritePolicy: { BucketName: !Ref Exports } Events: Nightly: Type: ScheduleV2 Properties: { ScheduleExpression: "cron(0 3 * * ? *)" }

Good to know

sam deploy --guided creates the stack and the functions' roles. Locally, sam local start-api runs the functions in Docker, while the bucket and schedule only exist once deployed. A database adds cost, since an always-on RDS instance costs more than the functions. Many short-lived Lambda connections can exhaust a Postgres instance, so RDS Proxy is the usual fix, and the RDS Data API, which runs queries over HTTPS, is only available for Aurora.

How to choose

  • Encore if you want the API, bucket and cron job in TypeScript, running locally and deployed to an AWS account you own.
  • Lightsail for a fixed monthly price and a server you are happy to manage.
  • Lambda and API Gateway for very low traffic where per-request pricing wins and you are fine writing the infrastructure.

Frequently asked questions

How do I set up AWS for a side project?

Create a separate account for the project under AWS Organizations, add a budget alert, lock away the root user and sign in through IAM Identity Center. Then deploy the app. With Encore, write the API in TypeScript, declare new Bucket("exports") and new CronJob("nightly-export", { schedule: "0 3 * * *", endpoint: exportLinks }), and deploy to your AWS account, where Encore provisions the compute and S3 bucket.

How do I avoid a surprise AWS bill on a side project?

Create a monthly cost budget with email alerts at, for example, 50 and 100 percent of a small amount. Budgets alert but do not stop resources, so also delete what you do not use and avoid always-on resources you do not need.

Should a side project use its own AWS account?

Yes. A separate account in an AWS Organization keeps its bill, permissions and resources apart from other work, and closing it later removes everything at once.

Is Lightsail good for a side project?

Lightsail bundles a virtual server, storage and transfer for a fixed monthly price, which is simple to reason about. You manage the server, deploys and backups yourself, and it does not connect as naturally to other AWS services.

Deploy to your cloud on AWS and Google Cloud
without managing infrastructure

Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.

~/orders — claude
Claude Code
Claude Code v2.1.180Opus 5.5~/orders