From 0839a8adc44edfd9e23688cf56ffff887234446a Mon Sep 17 00:00:00 2001 From: Florian Heuer Date: Fri, 8 Aug 2025 16:21:49 +0200 Subject: [PATCH] feature(iac): add dns module --- dns/README.md | 47 +++++++++++++++++ dns/dns.tf | 34 ++++++++++++ dns/outputs.tf | 46 +++++++++++++++++ dns/providers.tf | 9 ++++ dns/variables.tf | 132 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 268 insertions(+) create mode 100644 dns/README.md create mode 100644 dns/dns.tf create mode 100644 dns/outputs.tf create mode 100644 dns/providers.tf create mode 100644 dns/variables.tf diff --git a/dns/README.md b/dns/README.md new file mode 100644 index 0000000..9b072e8 --- /dev/null +++ b/dns/README.md @@ -0,0 +1,47 @@ +# Terraform module to create DNS zone + +## Example for main.tf + +```tf +locals { + stackit_project_id = "fb06b3bf-70b6-45bf-b1a4-e84708b26f92" + region = "eu01" + env = "dev" +} + +module "dns" { + source = "git::https://commerce-platform.git.onstackit.cloud/commerce-platform-public//terraform-modules/dns" + project_id = "my-stackit-project-id" + + zone_name = "example-zone" + dns_name = "example.com" + + contact_email = "admin@example.com" + description = "Main DNS zone - managed via Terraform" + default_ttl = 3600 + + record_name = "www.example.com" + record_type = "A" + records = ["192.0.29.1"] + ttl = 3600 + comment = "My example records - managed by Terraform" +} +``` + +## Usage Options + +### Use an Existing DNS Zone + +#### If you already have a DNS zone created in STACKIT, simply provide the `zone_id`: + +```hcl +module "dns" { + source = "git::https://commerce-platform.git.onstackit.cloud/commerce-platform-public//terraform-modules/dns" + project_id = "your-project-id" + + zone_id = "preexisting-zone-id" + record_name = "www.example.com" + record_type = "A" + records = ["192.0.29.1"] +} +``` diff --git a/dns/dns.tf b/dns/dns.tf new file mode 100644 index 0000000..3101bbf --- /dev/null +++ b/dns/dns.tf @@ -0,0 +1,34 @@ +resource "stackit_dns_zone" "this" { + count = var.zone_id == null ? 1 : 0 + project_id = var.stackit_project_id + name = var.dns_zone_name + dns_name = var.dns_zone_dns_name + + # Optional attributes + acl = var.dns_zone_acl + active = var.dns_zone_active + contact_email = var.dns_zone_contact_email + default_ttl = var.dns_zone_default_ttl + description = var.dns_zone_description + expire_time = var.dns_zone_expire_time + is_reverse_zone = var.dns_zone_is_reverse_zone + negative_cache = var.dns_zone_negative_cache + primaries = var.dns_zone_primaries + refresh_time = var.dns_zone_refresh_time + retry_time = var.dns_zone_retry_time + type = var.dns_zone_type +} + +resource "stackit_dns_record_set" "this" { + project_id = var.stackit_project_id + name = var.dns_record_set_name + records = var.dns_record_set_records + type = var.dns_record_set_type + #zone_id = var.dns_record_set_zone_id + zone_id = var.zone_id != null ? var.zone_id : stackit_dns_zone.this[0].zone_id + + # Optional + active = var.dns_record_set_active + comment = var.dns_record_set_comment + ttl = var.dns_record_set_ttl +} diff --git a/dns/outputs.tf b/dns/outputs.tf new file mode 100644 index 0000000..947a9d3 --- /dev/null +++ b/dns/outputs.tf @@ -0,0 +1,46 @@ +# === DNS Zone Outputs === +output "zone_id" { + value = var.zone_id != null ? var.zone_id : stackit_dns_zone.this[0].zone_id + description = "The DNS zone ID used or created" +} + +output "zone_primary_name_server" { + value = stackit_dns_zone.this.primary_name_server + description = "Primary name server" +} + +output "zone_state" { + value = stackit_dns_zone.this.state + description = "State of the DNS zone" +} + +output "zone_visibility" { + value = stackit_dns_zone.this.visibility + description = "Zone visibility" +} + +output "zone_record_count" { + value = stackit_dns_zone.this.record_count + description = "Number of DNS records in the zone" +} + +# === DNS Record Set Outputs === +output "record_set_fqdn" { + value = stackit_dns_record_set.this.fqdn + description = "Fully qualified domain name of the record" +} + +output "record_set_id" { + value = stackit_dns_record_set.this.record_set_id + description = "ID of the record set" +} + +output "record_set_state" { + value = stackit_dns_record_set.this.state + description = "State of the record set" +} + +output "record_set_error" { + value = stackit_dns_record_set.this.error + description = "Error during record creation (if any)" +} diff --git a/dns/providers.tf b/dns/providers.tf new file mode 100644 index 0000000..232c583 --- /dev/null +++ b/dns/providers.tf @@ -0,0 +1,9 @@ +terraform { + required_providers { + stackit = { + source = "stackitcloud/stackit" + version = "~> 0.59.0" + + } + } +} diff --git a/dns/variables.tf b/dns/variables.tf new file mode 100644 index 0000000..f254546 --- /dev/null +++ b/dns/variables.tf @@ -0,0 +1,132 @@ +variable "stackit_project_id" { + description = "STACKIT project ID to which the dns zone is associated." + type = string +} + +variable "zone_id" { + description = "ID of an existing DNS zone. If provided, no new zone will be created." + type = string + default = null +} + +# === DNS Zone variables === +variable "dns_zone_name" { + description = "Descriptive name of the DNS zone." + type = string +} + +variable "dns_zone_dns_name" { + description = "The actual zone name, e.g. example.com" + type = string +} + +variable "dns_zone_acl" { + description = "Access control list, e.g. 0.0.0.0/0,::/0" + type = string + default = null +} + +variable "dns_zone_active" { + description = "Whether the zone is active. Defaults to true" + type = bool + default = true +} + +variable "dns_zone_contact_email" { + description = "Contact email for the zone." + type = string + default = null +} + +variable "dns_zone_default_ttl" { + description = "The default value of the TTL for new resource records in the DNS zone. Time in seconds. Defaults to 3600" + type = number + default = 3600 +} + +variable "dns_zone_description" { + description = "An additional descriptive free text for the DNS zone." + type = string + default = null +} + +variable "dns_zone_expire_time" { + description = "If the secondary DNS server cannot perform a serial check in this interval, it must assume that its copy of the zone is obsolete and discard it. Time in seconds. Defaults to 1209600" + type = number + default = 1209600 +} + +variable "dns_zone_is_reverse_zone" { + description = "Indicates whether a zone is a reverse DNS zone or a forward zone. Both have a different set of allowed resource record types. Defaults to false" + type = bool + default = false +} + +variable "dns_zone_negative_cache" { + description = "The response about the non-existence of a resource record is cached for this interval. Time in seconds. Defaults to 60" + type = number + default = 60 +} + +variable "dns_zone_primaries" { + description = "List of primary nameservers (for secondary zone)" + type = list(string) + default = [] +} + +variable "dns_zone_refresh_time" { + description = "This is the amount of time a secondary DNS server will wait before checking with the primary for a new serial if a zone refresh fails. Time in seconds. Defaults to 3600" + type = number + default = 3600 +} + +variable "dns_zone_retry_time" { + description = "This is the amount of time a secondary DNS server waits before retrying a zone update if the update fails. Time in seconds. Defaults to 600" + type = number + default = 600 +} + +variable "dns_zone_type" { + description = "Zone type (primary or secondary). Defaults to primary" + type = string + default = "primary" +} + +# === DNS Record Set variables === +variable "dns_record_set_name" { + description = "Name of the DNS record (e.g. 'www.example.com')" + type = string +} + +variable "dns_record_set_records" { + description = "List of DNS record values" + type = list(string) +} + +variable "dns_record_set_type" { + description = "Record type (e.g. 'A', 'CNAME', etc.)" + type = string +} + +variable "dns_record_set_zone_id" { + description = "The zone ID for the DNS record" + type = string +} + +variable "dns_record_set_ttl" { + description = "Time to live (TTL) for the record" + type = number + default = 3600 +} + +variable "dns_record_set_active" { + description = "Whether the record set is active" + type = bool + default = true +} + +variable "dns_record_set_comment" { + description = "Optional comment for the record" + type = string + default = null +}