> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracecat.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS ECS Fargate

> Deploy self-hosted Tracecat to AWS ECS Fargate using Terraform: provision RDS, networking, secrets, and Temporal alongside Tracecat services in your own AWS account.

<Warning>
  This stack exposes Tracecat to the public internet.
  We've set the `auth_types` Terraform variable to `saml` by default.
  You must configure SAML before your first login or change `auth_types` to another method.
  See [Security](/self-hosting/security) for additional production hardening recommendations.
</Warning>

## Prerequisites

* [Terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli)
* AWS credentials configured for your target account and role
* A public [Route53 hosted zone](https://aws.amazon.com/route53/) (domain and hosted zone ID)
* `openssl` and AWS CLI (if using the helper secret script)

## Clone the repository

Clone the Tracecat repository and navigate to the Fargate deployment directory.

```bash theme={null}
git clone https://github.com/TracecatHQ/tracecat.git
cd tracecat/deployments/fargate
```

## Create core secrets

Tracecat requires four secrets. Generate them with `openssl`:

```bash theme={null}
# Service key (hex, 32 bytes) — used for internal service-to-service JWT signing
openssl rand -hex 32

# Signing secret (hex, 32 bytes) — used for webhook URL signing and HMAC operations
openssl rand -hex 32

# User auth secret (hex, 32 bytes) — used for password reset, email verification, OAuth state, and OIDC key derivation
openssl rand -hex 32

# DB encryption key (Fernet-compatible base64, 32 bytes) — used for encrypting secrets at rest
openssl rand 32 | base64 | tr -d '\n' | tr '+/' '-_'
```

<Warning>
  Store these securely. Losing `TRACECAT__DB_ENCRYPTION_KEY` makes encrypted credentials unrecoverable.
  Losing `TRACECAT__SIGNING_SECRET` invalidates existing webhook URLs and agent channel endpoint URLs.
</Warning>

See [Where to store them](/self-hosting/security#where-to-store-them) for the recommended storage on each deployment target, and which of these secrets can be rotated.

You can create these in AWS Secrets Manager manually or use the helper script:

```bash theme={null}
export AWS_DEFAULT_REGION=<aws-region>
./scripts/create-aws-secrets.sh
```

Save the resulting secret ARNs. You'll need them for Terraform variables.

## Configure authentication secrets (optional)

Depending on your chosen `auth_types` (e.g. `saml`, `oidc`, `oauth`), provide the necessary secret ARNs as Terraform variables.

For example, for SAML:

* `saml_idp_metadata_url_arn`

## Initialize and deploy

Initialize Terraform and apply the configuration.
`auth_superadmin_email` has no default — if you leave it unset, no one can sign in to the new deployment.

```bash theme={null}
terraform init

export TF_VAR_aws_region=<aws-region>
export TF_VAR_domain_name=<domain>
export TF_VAR_hosted_zone_id=<hosted-zone-id>

export TF_VAR_tracecat_db_encryption_key_arn=<secret-arn>
export TF_VAR_tracecat_service_key_arn=<secret-arn>
export TF_VAR_tracecat_signing_secret_arn=<secret-arn>
export TF_VAR_user_auth_secret_arn=<secret-arn>
export TF_VAR_auth_superadmin_email=<email>

# Optional but recommended
export TF_VAR_tracecat_image_tag=1.0.0-beta.50

terraform apply
```

Provisioning takes about 10-20 minutes due to RDS and ECS startup.

## Access Tracecat

Once deployed, access your instance at:

* UI: `https://<domain>`
* API docs: `https://<domain>/api/docs`
* MCP: `https://<domain>/mcp`

## First login

Set the first superadmin's email before anyone signs in. Until it is set, nobody can register, and the first account must match it. It takes one case-sensitive email address, so use the exact casing your identity provider sends.

| Deployment      | Setting                                                                      |
| :-------------- | :--------------------------------------------------------------------------- |
| Docker Compose  | `TRACECAT__AUTH_SUPERADMIN_EMAIL` in `.env`                                  |
| AWS ECS Fargate | `TF_VAR_auth_superadmin_email`, or `auth_superadmin_email` in your `.tfvars` |
| Kubernetes      | `tracecat.auth.superadminEmail` in `values.yaml`                             |

* Basic auth: sign up with that email, then log in.
* SSO: log in through your identity provider. Tracecat creates the account on first login.

The account becomes superadmin and owner of the default organization.

## Updating Tracecat

To update an existing Tracecat deployment on Fargate:

1. Pull the latest Fargate stack from the Tracecat repository to ensure you have the most recent infrastructure changes.
2. Change the `TF_VAR_tracecat_image_tag` variable to the desired image tag compatible with the stack, or remove the variable to default to the latest image tag.
3. Run `terraform apply` to apply the updates.

```bash theme={null}
cd tracecat/deployments/fargate
git pull origin main

# Set variables as before, then update the image tag
export TF_VAR_tracecat_image_tag=1.0.0-beta.50

terraform apply
```

## Temporal DB SSL enforcement

For the bundled Fargate `temporalio/auto-setup` deployment, `temporal_db_force_ssl` defaults to `false`:

```bash theme={null}
export TF_VAR_temporal_db_force_ssl=false
terraform apply
```

This setting applies only to the bundled Temporal RDS instance. It requires a DB reboot when changed and permits non-TLS connections to the Temporal database for compatibility with the current Fargate Temporal auto-setup flow.

If you are using Temporal Cloud or another external Temporal cluster, set `disable_temporal_autosetup=true` and point `temporal_cluster_url` at your external cluster. In that setup, `temporal_db_force_ssl` is typically unused because the bundled Temporal RDS instance is not created. If you run your own external Temporal PostgreSQL and want SSL-only enforcement there, set `TF_VAR_temporal_db_force_ssl=true`.

## FAQ

<AccordionGroup>
  <Accordion title="Is untrusted code execution safe on Fargate?">
    Fargate does not support the permissions model required by `nsjail`. Tracecat uses a fallback executor without `nsjail` isolation on Fargate.
    If you need the highest isolation for untrusted code execution (like custom registry actions or `core.script.run_python`), [deploy Tracecat on Kubernetes](/self-hosting/kubernetes), where `nsjail` is enabled by default.
  </Accordion>

  <Accordion title="What infrastructure does this stack create?">
    The Terraform stack deploys:

    * Public ALB, Route53 records, and ACM certificates
    * ECS cluster with Service Connect
    * RDS instances (core database and optional Temporal database)
    * ElastiCache Redis
    * S3 buckets for attachments, registry, and workflow artifacts
    * VPC endpoints for S3 and Secrets Manager
  </Accordion>

  <Accordion title="What happens if database migrations fail?">
    Migrations run in an init container during the API task startup. The API container only starts if migrations succeed. If migrations fail, the deployment pauses and dependent services (`worker`, `executor`) will not update.
  </Accordion>
</AccordionGroup>
