# AWS

> Create a single EC2 server for Grovs with the CloudFormation template.

Source: https://docs.grovs.io/docs/self-hosting/clouds/aws

[Open CloudFormation](https://console.aws.amazon.com/cloudformation/home#/stacks/create/template)

## When to use

You want Grovs on one EC2 instance in your AWS account. The [CloudFormation template](https://github.com/grovs-io/self-host/blob/main/deploy/aws/cloudformation.yaml) creates a dedicated VPC, public subnet, security group, static IPv4 address and one Ubuntu 24.04 EC2 instance. Grovs runs there with Docker Compose. PostgreSQL, Redis, ClickHouse and uploads use persistent Docker volumes on its encrypted EBS disk. This is a single-server deployment, not an HA cluster.

## Prerequisites

| Requirement          | Notes                                                                                                                                          |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| AWS permissions      | Create the template's resources, create and pass IAM roles, and read the public Ubuntu AMI parameter from SSM                                  |
| Budget               | You pay for the instance, EBS storage and public IPv4. The default is a `t3.xlarge` with 100 GiB of gp3 storage. Check regional pricing first. |
| A domain you control | For the [DNS records](https://docs.grovs.io/docs/self-hosting/get-started/deployment#dns)                                                      |

## 1. Prepare DNS and firewall

The template creates the security group. No SSH port is open publicly: you connect through Session Manager. Point the DNS records at the static IP from the stack Outputs after step 2.

## 2. Create the server

### 1. Upload the template

Download `deploy/aws/cloudformation.yaml` from the repository. In your region, open **CloudFormation → Create stack → With new resources**, select **Upload a template file** and upload it.

### 2. Fill in the parameters

Set `AppDomain`, `AdminEmail` and `GrovsVersion`. For `GrovsVersion`, use the version on the [latest completed release](https://github.com/grovs-io/self-host/releases/latest), replacing any older template default. It selects matching backend and dashboard images from GHCR.

### 3. Choose the stack files

Keep `StackRef=main` or pin a reviewed commit that contains the deployment files. `StackRef` selects deployment files independently of the image version, because application release tags can predate the cloud scripts.

### 4. Create the stack

Review the resources and acknowledge IAM creation. The instance role grants Session Manager connectivity. Create the stack, then copy `IpAddress` and `InstanceId` from **Outputs**.

## 3. Install Grovs

CloudFormation completion means the VM exists. **Application setup continues inside it**: package installation, image pulls and migrations take a while before the dashboard is up. Point the DNS records at `IpAddress`.

## 4. Deploy and verify

In **EC2 → Instances → Connect → Session Manager**, open the instance and run:

```bash
sudo systemctl status grovs --no-pager
sudo tail -100 /var/log/cloud-init-output.log
sudo cat /opt/grovs/.env
```

Sign in at `https://dashboard.<AppDomain>` with `BOOTSTRAP_ADMIN_EMAIL` and `BOOTSTRAP_ADMIN_PASSWORD`. Setup writes secrets to root-readable files; they are not in CloudFormation parameters or Outputs. Finish with the checks in [Verify](https://docs.grovs.io/docs/self-hosting/get-started/deployment#verify).

## Upgrades

The checkout and `.env` live in `/opt/grovs`, and `grovs.service` starts the stack on boot. Run `sudo -i`, then `cd /opt/grovs` for the usual Compose commands. Back up PostgreSQL, ClickHouse, uploads and `.env`, then follow [Upgrades](https://docs.grovs.io/docs/self-hosting/operate/upgrades). Updating the CloudFormation parameters is not a supported in-place application upgrade.

## Gotchas

- If Session Manager is unavailable, check the instance profile, outbound network access and SSM agent status. The operator also needs permission to start an SSM session. See [AWS Session Manager prerequisites](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-prerequisites.html).
- Deleting the stack terminates the VM and releases its public IP. The root EBS volume is **retained** (`DeleteOnTermination: false`), so its data survives but keeps incurring storage charges. Identify and snapshot it before deletion; deleting retained volumes is a separate, irreversible operation. A retained disk is not a database backup.
