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

# Add a new environment

> Set up a new Authsignal tenant, such as QA or production, from the shared module.

Terraform sets up a new tenant from the module. This example adds QA. Production works the same way.

## Prerequisites

* A dev tenant that Terraform already manages, as in [Import the dev tenant into Terraform](/knowledge-base/terraform/import-dev).
* A CI pipeline that runs Terraform for the new environment, as in [Running QA and production](/knowledge-base/terraform/repository-setup#running-qa-and-production).

## 1. Create the tenant

Create the tenant in the portal and generate its Management API secret key. Don't configure anything else in it.

Store the key, the tenant ID, the host, and any secret values, such as `sendgrid_api_key`, as secrets for the QA pipeline, as in [Running QA and production](/knowledge-base/terraform/repository-setup#running-qa-and-production). Don't keep the key on your machine.

## 2. Create the folder

Create `envs/qa` and copy in only `main.tf`, `variables.tf`, `terraform.tfvars`, and `.terraform.lock.hcl` from `envs/dev`. The lock file keeps QA on the same provider version as dev.

Don't copy the `.terraform` folder, any `terraform.tfstate` files, `imports.tf`, or `tfplan`. State belongs to one tenant. Copying it would make Terraform think QA already has dev's resources.

If you use a [backend](/knowledge-base/terraform/repository-setup#where-state-is-stored), change its `key` in `envs/qa/main.tf` so QA gets its own state, such as `authsignal/qa.tfstate`. If QA and production state is kept in a separate bucket, change `bucket` too. With HCP Terraform, change the workspace `name` in the `cloud` block, such as to `authsignal-qa`. Otherwise QA shares dev's workspace and state. Then set the QA values.

```hcl theme={null}
# envs/qa/terraform.tfvars
email_otp_webhook_url    = "https://api.qa.example.com/authsignal/email-otp"
passkey_relying_party    = "qa.example.com"
passkey_expected_origins = ["https://qa.example.com"]
tenant_name              = "Example (QA)"
```

The copied `terraform.tfvars` still has dev's values, so check every line. Take extra care with the web addresses. Authsignal sends each one-time code to `email_otp_webhook_url`, so if it still has dev's address, the new tenant sends its users' codes to dev. Any address in `passkey_expected_origins` can sign users in to the tenant with their passkeys, so list only the new environment's own addresses.

## 3. Import the theme

Every tenant already has a theme, and the provider can't create one, so it has to be imported. Everything else is created, since a new tenant has no authenticator configurations, flows, or message overrides.

```hcl theme={null}
# envs/qa/imports.tf
import {
  to = module.authsignal.authsignal_theme.theme
  id = "theme"
}
```

If someone has already set message overrides in the new tenant, the provider refuses to create the resource and asks for an import. Add the messages import block from [Import the dev tenant into Terraform](/knowledge-base/terraform/import-dev) in that case.

## 4. Plan

Commit `envs/qa`, including `imports.tf`, and open a pull request. After it merges, run the QA pipeline. With the example module, the plan shows:

```text theme={null}
Plan: 1 to import, 4 to add, 1 to change, 0 to destroy.
```

The numbers depend on what's in your module. In this example:

* The four additions are the two authenticators, the flow, and the message overrides.
* The theme is both the import and the change. The new tenant has the default theme, so Terraform imports it and updates it to match dev in one step. It is marked `(imported from "theme")` in the plan.

## 5. Apply

Approve the apply in the pipeline. Then delete `envs/qa/imports.tf` and merge that too. The import is done, so the block isn't needed any more.

## Verify

Run the QA pipeline again. Its plan should report `No changes`. Test sign-in on the new tenant.

Follow the same steps for production. When dev, QA, and production all report `No changes`, they are aligned.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.