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

# Manage DNS zones and records via Terraform v0

With the Gcore Terraform provider v0, teams define DNS zones and records in configuration files, then apply them consistently across environments without managing DNS through the Portal.

The following resources are supported: DNS zones with SOA and DNSSEC configuration, A, AAAA, CNAME, MX, TXT, SRV, CAA records, geo-balancing with geographic filtering, and DNS failover with health checks. Provider v0 does not support PTR records — use [provider v2](/dns/dns-plugins/manage-dns-with-terraform-v2) instead.

Provider installation is in the [Terraform overview](/developer-tools/terraform/overview); to upgrade, use the [Terraform provider v2](/dns/dns-plugins/manage-dns-with-terraform-v2) article and the [migration guide](/developer-tools/terraform/migrate-v0-to-v2).

## Workflow

Add resource configuration to `main.tf`, then run:

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

Review the output, then apply:

```sh theme={null}
terraform apply
```

## Create a DNS zone

The `gcore_dns_zone` resource manages DNS zones in Gcore.

### Add a basic zone

The minimum configuration requires only the zone name.

1. Open the `main.tf` file with the Gcore provider configuration.
2. Copy the code below to the file and customize the values:

```hcl theme={null}
resource "gcore_dns_zone" "example_zone" {
  name = "example.com"
}
```

### Configure optional zone settings

The following configuration enables DNSSEC and sets the SOA timing, contact, and primary server fields.

1. Open the `main.tf` file with the Gcore provider configuration.
2. Copy the code below to the file and customize the highlighted values:

```hcl theme={null}
resource "gcore_dns_zone" "example_zone" {
  name           = "example.com"
  dnssec         = true
  enabled        = true
  contact        = "admin@example.com"
  refresh        = 3600
  retry          = 1800
  expiry         = 604800
  nx_ttl         = 3600
  primary_server = "ns1.example.com."
}
```

3. Configure the zone.

* Specify `name`.
* (optional) Add `enabled = true` to allow records to resolve on DNS servers.
* (optional) Add `dnssec = true` to enable DNSSEC signing for the zone.
* (optional) Specify `contact` — the administrator email recorded in the SOA record.
* (optional) Specify `refresh` — how often secondary servers check for zone changes (seconds).
* (optional) Specify `retry` — how long secondary servers wait before retrying a failed refresh (seconds).
* (optional) Specify `expiry` — how long secondary servers serve the zone without a successful refresh (seconds).
* (optional) Specify `nx_ttl` — TTL for negative responses (seconds).
* (optional) Specify `primary_server` — the primary master name server for the zone.

<Tip>
  Webhook notifications for zone changes can be configured using the `meta` block:

  ```hcl theme={null}
  meta = {
    webhook_url    = "https://hooks.example.com/dns-changes"
    webhook_method = "POST"
  }
  ```
</Tip>

## Add DNS records

The `gcore_dns_zone_record` resource manages individual DNS records within a zone. Required fields are `zone`, `domain`, `type`, and at least one `resource_record` block. The `ttl` field is optional.

### A record

An A record maps a hostname to one or more IPv4 addresses.

1. Open the `main.tf` file with the Gcore provider configuration.
2. Copy the code below to the file and customize the values:

```hcl theme={null}
resource "gcore_dns_zone_record" "example_a" {
  zone   = gcore_dns_zone.example_zone.name
  domain = gcore_dns_zone.example_zone.name
  type   = "A"
  ttl    = 300

  resource_record {
    content = "203.0.113.1"
  }
  resource_record {
    content = "203.0.113.2"
  }
}
```

3. Configure the record.

* Specify `zone` — the DNS zone name.
* Specify `domain` — the full record name (for the zone apex, use the zone name).
* Specify `type = "A"`.
* Add one `resource_record` block per IP address. Specify `content` — the IPv4 address.
* (optional) Specify `ttl`.

### AAAA record

An AAAA record maps a hostname to one or more IPv6 addresses.

1. Open the `main.tf` file with the Gcore provider configuration.
2. Copy the code below to the file and customize the values:

```hcl theme={null}
resource "gcore_dns_zone_record" "aaaa" {
  zone   = gcore_dns_zone.example_zone.name
  domain = gcore_dns_zone.example_zone.name
  type   = "AAAA"
  ttl    = 300

  resource_record {
    content = "2001:db8::1"
  }
  resource_record {
    content = "2001:db8::2"
  }
}
```

3. Configure the record.

* Specify `zone` — the DNS zone name.
* Specify `domain` — the full record name.
* Specify `type = "AAAA"`.
* Add one `resource_record` block per IPv6 address. Specify `content` — the IPv6 address.
* (optional) Specify `ttl`.

### CNAME record

A CNAME record creates an alias that points one hostname to another.

1. Open the `main.tf` file with the Gcore provider configuration.
2. Copy the code below to the file and customize the values:

```hcl theme={null}
resource "gcore_dns_zone_record" "www" {
  zone   = gcore_dns_zone.example_zone.name
  domain = "www.example.com"
  type   = "CNAME"
  ttl    = 300

  resource_record {
    content = "example.com."
  }
}
```

3. Configure the record.

* Specify `zone`.
* Specify `domain` — the alias name.
* Specify `type = "CNAME"`.
* Specify `content` — the target domain with a trailing dot.
* (optional) Specify `ttl`.

### MX record

An MX record specifies mail servers for the domain, each with a priority value.

1. Open the `main.tf` file with the Gcore provider configuration.
2. Copy the code below to the file and customize the values:

```hcl theme={null}
resource "gcore_dns_zone_record" "mx" {
  zone   = gcore_dns_zone.example_zone.name
  domain = gcore_dns_zone.example_zone.name
  type   = "MX"
  ttl    = 3600

  resource_record {
    content = "10 mail.example.com."
  }
  resource_record {
    content = "20 mail-backup.example.com."
  }
}
```

3. Configure the record.

* Specify `zone` and `domain`.
* Specify `type = "MX"`.
* Add one `resource_record` block per mail server. Specify `content` as `"<priority> <hostname>."` — priority and hostname separated by a space, hostname with a trailing dot.
* (optional) Specify `ttl`.

### TXT record

A TXT record holds arbitrary text, commonly used for SPF, DKIM, and domain verification.

1. Open the `main.tf` file with the Gcore provider configuration.
2. Copy the code below to the file and customize the values:

```hcl theme={null}
resource "gcore_dns_zone_record" "spf" {
  zone   = gcore_dns_zone.example_zone.name
  domain = gcore_dns_zone.example_zone.name
  type   = "TXT"
  ttl    = 3600

  resource_record {
    content = "v=spf1 include:_spf.google.com ~all"
  }
}
```

3. Configure the record.

* Specify `zone` and `domain`.
* Specify `type = "TXT"`.
* Specify `content` — the text value, such as an SPF, DKIM, or domain verification string.
* (optional) Specify `ttl`.

### CAA record

A CAA record specifies which certificate authorities are allowed to issue certificates for the domain.

1. Open the `main.tf` file with the Gcore provider configuration.
2. Copy the code below to the file and customize the values:

```hcl theme={null}
resource "gcore_dns_zone_record" "caa" {
  zone   = gcore_dns_zone.example_zone.name
  domain = gcore_dns_zone.example_zone.name
  type   = "CAA"
  ttl    = 3600

  resource_record {
    content = "0 issue \"letsencrypt.org\""
  }
}
```

3. Configure the record.

* Specify `zone` and `domain`.
* Specify `type = "CAA"`.
* Specify `content` as `"<flags> <tag> \"<value>\""` — flags, tag (`issue`, `issuewild`, or `iodef`), and the CA value in quotes.
* (optional) Specify `ttl`.

### SRV record

An SRV record specifies the location of a service, including its priority, weight, port, and target hostname.

1. Open the `main.tf` file with the Gcore provider configuration.
2. Copy the code below to the file and customize the values:

```hcl theme={null}
resource "gcore_dns_zone_record" "srv" {
  zone   = gcore_dns_zone.example_zone.name
  domain = "_sip._tcp.example.com"
  type   = "SRV"
  ttl    = 300

  resource_record {
    content = "10 20 5060 sip.example.com."
  }
}
```

3. Configure the record.

* Specify `domain` — the service name in the format `_service._proto.example.com`.
* Specify `type = "SRV"`.
* Specify `content` as `"<priority> <weight> <port> <target>."` — four values separated by spaces, target with a trailing dot.
* (optional) Specify `ttl`.

## Configure geo-balancing

Geo-balancing returns different IP addresses based on the client's geographic location, using `filter` and `meta` blocks within a record.

1. Open the `main.tf` file with the Gcore provider configuration.
2. Copy the code below to the file and customize the values:

```hcl theme={null}
resource "gcore_dns_zone_record" "geo_a" {
  zone   = gcore_dns_zone.example_zone.name
  domain = gcore_dns_zone.example_zone.name
  type   = "A"
  ttl    = 120

  filter {
    type   = "geodistance"
    limit  = 1
    strict = true
  }

  resource_record {
    content = "203.0.113.1"
    meta {
      latlong    = [52.3676, 4.9041]
      continents = ["europe"]
      countries  = ["nl"]
    }
  }

  resource_record {
    content = "198.51.100.1"
    meta {
      latlong    = [40.7128, -74.0060]
      continents = ["north_america"]
      countries  = ["us"]
    }
  }
}
```

3. Configure geo-balancing.

* Add a `filter` block. Specify `type` — the filter algorithm (`geodistance`, `geodns`, `country`, `continent`, `asn`, `ip`, `weighted_shuffle`, `first_n`, or `default`).
* (optional) Specify `limit` — the maximum number of records returned per query. Set to `0` for no limit.
* (optional) Add `strict = true` to return no records if none match the filter, instead of falling back to all records.
* Add `meta` inside each `resource_record` to associate geographic data with that IP.
  * Specify `latlong` — `[latitude, longitude]` coordinates used by the `geodistance` filter.
  * (optional) Specify `continents` — list of continent codes (`europe`, `north_america`, `south_america`, `asia`, `africa`, `oceania`).
  * (optional) Specify `countries` — list of two-letter country codes as defined in the [geobalancing](/dns/dns-records/configure-weight-balancing-and-geobalancing) article.

## Set up failover with health checks

[Health checks](/dns/dns-failover/configure-and-use-dns-failover) automatically remove unhealthy records from DNS responses, directing traffic only to reachable endpoints.

1. Open the `main.tf` file with the Gcore provider configuration.
2. Copy the code below to the file and customize the values:

```hcl theme={null}
resource "gcore_dns_zone_record" "failover_a" {
  zone   = gcore_dns_zone.example_zone.name
  domain = "app.example.com"
  type   = "A"
  ttl    = 120

  filter {
    type   = "is_healthy"
    limit  = 0
    strict = true
  }

  resource_record {
    content = "203.0.113.1"
    enabled = true
  }

  meta {
    failover {
      frequency        = 300
      protocol         = "HTTP"
      host             = "app.example.com"
      method           = "GET"
      url              = "/health"
      port             = 443
      tls              = true
      http_status_code = 200
      timeout          = 10
    }
  }
}
```

3. Configure the health check.

* Add `filter { type = "is_healthy" }` to exclude unhealthy records from DNS responses.
* Add `enabled = true` inside each `resource_record` to include it in health check rotation.
* Add a `meta { failover { } }` block to the record and configure the health check:
  * Specify `protocol` — `HTTP`, `TCP`, `UDP`, or `ICMP`.
  * Specify `port`.
  * Specify `frequency` — check interval from 10 to 3600 seconds.
  * Specify `timeout` — response timeout from 1 to 10 seconds.
  * (optional, HTTP only) Specify `host`, `method`, `url`, `http_status_code`, and `tls`.

## Import existing DNS resources

To import existing DNS zones and records from the [Gcore Customer Portal](https://portal.gcore.com) into Terraform state, add the corresponding resource blocks to `main.tf` and run the import commands below.

To import an existing DNS zone:

```shell theme={null}
terraform import gcore_dns_zone.example_zone example.com
```

To import an existing DNS record, use the format `zone:domain:type`:

```shell theme={null}
terraform import gcore_dns_zone_record.example_a example.com:example.com:A
```

<Tip>
  After importing, run `terraform plan` to verify the configuration matches the imported state. If there are differences, update `main.tf` to match the actual resource settings.
</Tip>
