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

# Importing Resources

> Import existing DevHelm resources into Terraform state

Import resources created in the dashboard or via the CLI into Terraform management without recreating them.

## Import syntax

```bash theme={null}
terraform import <resource_type>.<name> "<import_id>"
```

## Import IDs by resource

Each resource type uses a different identifier for import:

| Resource                              | Import ID                                                 | Example                                                                                |
| ------------------------------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `devhelm_monitor`                     | Monitor **name**                                          | `terraform import devhelm_monitor.api "API Health"`                                    |
| `devhelm_alert_channel`               | Channel **name**                                          | `terraform import devhelm_alert_channel.slack "Slack Alerts"`                          |
| `devhelm_notification_policy`         | Policy **name**                                           | `terraform import devhelm_notification_policy.oncall "On-call routing"`                |
| `devhelm_tag`                         | Tag **name**                                              | `terraform import devhelm_tag.prod "production"`                                       |
| `devhelm_environment`                 | Environment **slug**                                      | `terraform import devhelm_environment.staging "staging"`                               |
| `devhelm_secret`                      | Secret **key**                                            | `terraform import devhelm_secret.token "API_TOKEN"`                                    |
| `devhelm_webhook`                     | Webhook **URL**                                           | `terraform import devhelm_webhook.events "https://hooks.example.com/devhelm"`          |
| `devhelm_resource_group`              | Group **name** or **slug**                                | `terraform import devhelm_resource_group.payments "Payment Service"`                   |
| `devhelm_resource_group_membership`   | `<group_id>/<membership_id\|monitor_id\|subscription_id>` | `terraform import devhelm_resource_group_membership.api "<group-uuid>/<monitor-uuid>"` |
| `devhelm_dependency`                  | Service **slug**                                          | `terraform import devhelm_dependency.github "github"`                                  |
| `devhelm_status_page`                 | Page **slug**                                             | `terraform import devhelm_status_page.public "acme-status"`                            |
| `devhelm_status_page_component`       | `<status_page_id>/<component_id>`                         | `terraform import devhelm_status_page_component.api "<page-uuid>/<component-uuid>"`    |
| `devhelm_status_page_component_group` | `<status_page_id>/<group_id>`                             | `terraform import devhelm_status_page_component_group.core "<page-uuid>/<group-uuid>"` |
| `devhelm_status_page_custom_domain`   | `<status_page_id>/<custom_domain_id>`                     | `terraform import devhelm_status_page_custom_domain.www "<page-uuid>/<domain-uuid>"`   |

<Note>
  Every resource also accepts its **UUID** as the import ID. Name-based
  imports fail with an ambiguity error when multiple resources share the name
  (names are not unique within an org) — import by UUID in that case.
  `devhelm_status_page_custom_domain_verification` is the one resource that
  cannot be imported: it is a synthetic verification barrier with no
  server-side counterpart.
</Note>

## Step-by-step

### 1. Write the resource block

Before importing, create the Terraform resource block that matches the existing resource:

```hcl theme={null}
resource "devhelm_monitor" "api_health" {
  name              = "API Health"
  type              = "HTTP"
  frequency_seconds = 60
  regions           = ["us-east"]

  config = jsonencode({
    url    = "https://api.example.com/health"
    method = "GET"
  })
}
```

### 2. Run import

```bash theme={null}
terraform import devhelm_monitor.api_health "API Health"
```

### 3. Run plan

Verify the imported state matches your configuration:

```bash theme={null}
terraform plan
```

If the plan shows changes, adjust your HCL to match the existing resource's configuration.

## Bulk import

For importing many resources, use a shell loop:

```bash theme={null}
for name in "API Health" "Marketing Site" "Database Port"; do
  terraform import "devhelm_monitor.$(echo $name | tr ' ' '_' | tr '[:upper:]' '[:lower:]')" "$name"
done
```

## Secrets import

Secret values are write-only, so an import stores the placeholder `IMPORTED_PLACEHOLDER` as the `value` in state. The next plan shows drift until you set the real value in HCL:

```hcl theme={null}
resource "devhelm_secret" "api_token" {
  key   = "API_TOKEN"
  value = var.api_token
}
```

```bash theme={null}
terraform import devhelm_secret.api_token "API_TOKEN"
```

## Next steps

<CardGroup cols={2}>
  <Card title="Terraform in CI/CD" icon="rotate" href="/mac/terraform/ci-cd">
    Automate plan and apply in CI pipelines.
  </Card>

  <Card title="Data sources" icon="database" href="/mac/terraform/data-sources">
    Reference resources without importing them.
  </Card>
</CardGroup>
