Quickstart

Install the CLI, create a project, deploy a bucket, and tear it down again.

1. Install the Anvil CLI

The CLI drives the Pulumi engine underneath every Anvil program.

curl -fsSL https://raw.githubusercontent.com/anvil-cloud/anvil/master/install.sh | sh

Installs anvil and the provider to /usr/local/bin. Works on Apple Silicon and Intel.

2. Install the SDK

Install the TypeScript SDK for your project. Requires Node.js 18+. Project setup below installs it too, so this is for adding Anvil to an existing project.

npm install @anvil-cloud/sdk

Install the Python SDK for your project. Requires Python 3.8+. Project setup below installs it too, so this is for adding Anvil to an existing project.

pip install anvil-cloud

Install the Go SDK for your project. Requires Go 1.22+. Project setup below installs it too, so this is for adding Anvil to an existing project.

go get github.com/anvil-cloud/anvil/sdk/go/anvil

anvil deploy uses whatever python3 is on your PATH, so activate your project's virtualenv first (source .venv/bin/activate).

3. Create a project

Everything below follows the language you picked above.

anvil init --name my-app --lang ts
cd my-app
npm install
anvil init --name my-app --lang python
cd my-app
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
anvil init --name my-app --lang go
cd my-app
go mod tidy

4. Declare a bucket

Replace anvil.config.tsanvil.config.pyanvil.config.go with one bucket. The tags default applies to every resource in the program.

import { App } from '@anvil-cloud/sdk';
import * as anvil from '@anvil-cloud/sdk';

export default new App({
  defaults: {
    tags: {
      project: 'my-app',
      costCenter: 'platform-eng',
    },
  },
  run(ctx) {
    const uploads = new anvil.aws.Bucket('uploads');

    ctx.export('bucketName', uploads.bucketName);
  },
});
import anvil_cloud as anvil

def main(ctx: anvil.Context) -> None:
    uploads = anvil.aws.Bucket("uploads")

    ctx.export("bucket_name", uploads.bucket_name)


anvil.run(anvil.AppConfig(
    defaults=anvil.DefaultsConfig(
        tags={"project": "my-app", "costCenter": "platform-eng"},
    ),
    run=main,
))
package main

import (
	"github.com/anvil-cloud/anvil/sdk/go/anvil"
	anvilaws "github.com/anvil-cloud/anvil/sdk/go/anvil/aws"
)

func main() {
	anvil.Run(anvil.AppConfig{
		Defaults: &anvil.DefaultsConfig{
			Tags: map[string]string{"project": "my-app", "costCenter": "platform-eng"},
		},
		Run: func(ctx *anvil.Context) error {
			uploads, err := anvilaws.NewBucket(ctx.PulumiCtx(), "uploads", nil)
			if err != nil {
				return err
			}

			ctx.Export("bucketName", uploads.BucketName)
			return nil
		},
	})
}

Every Anvil component has secure defaults, so the bucket is private and encrypted without any extra arguments. See the Bucket docs for what you can change.

5. Preview, then deploy

Preview shows what will change before anything is created.

anvil preview
anvil deploy

6. Tear it down

Destroy needs the stage named explicitly, so you can't tear down the wrong one by accident. Your stage is listed under stages in anvil.yaml.

anvil destroy --stage <stage>

Resources that hold data — DSQL clusters, DynamoDB tables and Cognito user pools — are protected and kept. Add --force to remove their protection and delete them too, data included. Anvil lists what will be deleted and asks you to type the stage name first.