diff --git a/example/main.tf b/example/main.tf index 2d6c014..d185416 100644 --- a/example/main.tf +++ b/example/main.tf @@ -1,9 +1,12 @@ module "project" { source = "../project" - name = "project-1" + name = "project-123" + labels = { + "example" = "test" + } organization_id = var.organization_id - owner_email = "maximilian.schlenz@stackit.cloud" + owner_email = "maximilian.schlenz@stackit.cloud" } module "security_groups" { @@ -13,10 +16,47 @@ module "security_groups" { project_id = module.project.project_id name = each.value.name - description = each.value.description + description = each.value.description != null ? each.value.description : "" rules = each.value.rules } +locals { + security_group_ids_by_name = { + for key, m in module.security_groups : + m.name => m.security_group_id + } +} + +module "net" { + depends_on = [module.security_groups] + source = "../network" + + for_each = var.networks + + project_id = module.project.project_id + name = each.value.name + + # IPv4 and IPv6 settings + ipv4_gateway = each.value.ipv4_gateway + ipv4_nameservers = each.value.ipv4_nameservers + ipv4_prefix = each.value.ipv4_prefix + ipv4_prefix_length = each.value.ipv4_prefix_length + + ipv6_gateway = each.value.ipv6_gateway + ipv6_nameservers = each.value.ipv6_nameservers + ipv6_prefix = each.value.ipv6_prefix + ipv6_prefix_length = each.value.ipv6_prefix_length + + no_ipv4_gateway = each.value.no_ipv4_gateway + no_ipv6_gateway = each.value.no_ipv6_gateway + routed = each.value.routed + labels = each.value.labels + + # NIC options + nics = each.value.nics + security_group_ids_by_name = local.security_group_ids_by_name +} + # module "postgres" { # source = "../postgres" @@ -34,29 +74,6 @@ module "security_groups" { # databases = each.value.databases # } -module "net" { - depends_on = [module.security_groups] - source = "../network" - - for_each = var.networks - - project_id = module.project.project_id - name = each.value.name - - ipv4_nameservers = each.value.ipv4_nameservers - labels = each.value.labels - - nic_ipv4 = each.value.nic_ipv4 - nic_name = each.value.nic_name - nic_allowed_addresses = each.value.nic_allowed_addresses - nic_labels = each.value.nic_labels - nic_security = each.value.nic_security - - nic_security_group_ids = [ - module.security_groups["ssh_ingress_group"].security_group_id, - ] -} - # module "ske" { # source = "../ske" diff --git a/example/providers.tf b/example/providers.tf index 04db4e1..21bfe9e 100644 --- a/example/providers.tf +++ b/example/providers.tf @@ -3,7 +3,7 @@ terraform { required_providers { stackit = { source = "stackitcloud/stackit" - version = "0.56.0" + version = "0.54.0" } } } diff --git a/example/terraform.tfvars b/example/terraform.tfvars index ef8304b..d8c6bc8 100644 --- a/example/terraform.tfvars +++ b/example/terraform.tfvars @@ -1,7 +1,7 @@ region = "eu01" service_account_token = "" project_id = "" -organization_id = "03a34540-3c1a-4794-b2c6-7111ecf824ef" +organization_id = "03a34540-3c1a-4794-b2c6-7111ecf824ef" service_account_key_path = "/Users/schlenz/sa-key-dd5fa2c9-1651-4da7-8404-9ac4fe9bc3d5.json" security_groups = { @@ -91,21 +91,51 @@ security_groups = { # } networks = { - # web = { - # name = "web-net" - # ipv4_nameservers = ["1.1.1.1", "8.8.8.8"] - # labels = { - # env = "prod" - # } - # } + wan_network = { + name = "wan_network" + ipv4_nameservers = ["1.1.1.1", "8.8.8.8"] + ipv4_prefix_length = 24 + ipv4_prefix = "10.219.0.0/24" + routed = true + } + lan_network1 = { + name = "lan_network1" + ipv4_prefix_length = 24 + ipv4_prefix = "10.220.1.0/24" + routed = true + nics = { + p2_lan1 = { + nic_name = "P2LAN1" + nic_ipv4 = "10.220.1.32" + nic_security = true + nic_security_group_names = ["ssh-ingress-group"] + } + } + } + lan_network2 = { + name = "lan_network2" + ipv4_prefix_length = 24 + ipv4_prefix = "10.221.0.0/24" + routed = true + } + lan_network3 = { + name = "lan_network3" + ipv4_nameservers = ["1.1.1.1", "8.8.8.8"] + ipv4_prefix_length = 24 + ipv4_prefix = "10.223.3.0/24" + routed = true + } + wan = { + name = "MGMT" + ipv4_nameservers = ["1.1.1.1", "8.8.8.8"] + ipv4_prefix_length = 24 + nic_ipv4 = "10.224.0.254" + } db = { name = "db-net" nic_ipv4 = "10.0.0.126" nic_security = true - security_groups = { - - } } } diff --git a/example/variables.tf b/example/variables.tf index be98dee..496493e 100644 --- a/example/variables.tf +++ b/example/variables.tf @@ -77,23 +77,45 @@ variable "security_groups" { # })) # } +# Network definition map variable "networks" { type = map(object({ name = string - ipv4_nameservers = optional(list(string)) - labels = optional(map(string)) + # IPv4 settings + ipv4_gateway = optional(string) + ipv4_nameservers = optional(list(string)) + ipv4_prefix = optional(string) + ipv4_prefix_length = optional(number) - nic_ipv4 = optional(string) - nic_name = optional(string) + # IPv6 settings + ipv6_gateway = optional(string) + ipv6_nameservers = optional(list(string)) + ipv6_prefix = optional(string) + ipv6_prefix_length = optional(number) - nic_allowed_addresses = optional(list(string)) - nic_labels = optional(map(string)) - nic_security = optional(bool) - nic_security_group_ids = optional(list(string)) + # Flags & labels + labels = optional(map(string)) + no_ipv4_gateway = optional(bool) + no_ipv6_gateway = optional(bool) + routed = optional(bool) + + # NIC‑specific options + nics = optional(map(object({ + nic_ipv4 = optional(string) + nic_name = string + nic_allowed_addresses = optional(list(string)) + nic_labels = optional(map(string)) + nic_security = optional(bool) + nic_security_group_ids = optional(list(string)) + nic_security_group_names = optional(list(string)) + }))) })) + + default = {} } + # variable "ske_clusters" { # type = map(object({ # name = string diff --git a/network/main.tf b/network/main.tf index b010a34..0f7b638 100644 --- a/network/main.tf +++ b/network/main.tf @@ -1,31 +1,41 @@ resource "stackit_network" "this" { - project_id = var.project_id - name = var.name + project_id = var.project_id + name = var.name + labels = var.labels - ipv4_gateway = var.routed == false ? var.ipv4_gateway : null + # IPv4 settings + ipv4_gateway = var.ipv4_gateway ipv4_nameservers = var.ipv4_nameservers ipv4_prefix = var.ipv4_prefix ipv4_prefix_length = var.ipv4_prefix_length - ipv6_gateway = var.routed == false ? var.ipv6_gateway : null + + # IPv6 settings + ipv6_gateway = var.ipv6_gateway ipv6_nameservers = var.ipv6_nameservers ipv6_prefix = var.ipv6_prefix ipv6_prefix_length = var.ipv6_prefix_length - labels = var.labels - no_ipv4_gateway = var.no_ipv4_gateway - no_ipv6_gateway = var.no_ipv6_gateway - routed = var.routed + + no_ipv4_gateway = var.no_ipv4_gateway + no_ipv6_gateway = var.no_ipv6_gateway + routed = var.routed } -resource "stackit_network_interface" "static" { - count = var.nic_ipv4 == null ? 0 : 1 +resource "stackit_network_interface" "nics" { + for_each = var.nics != null ? var.nics : {} - network_id = stackit_network.this.network_id project_id = var.project_id - - ipv4 = var.nic_ipv4 - labels = var.nic_labels - name = var.nic_name != null ? var.nic_name : "${var.name}-nic" - security = var.nic_security - security_group_ids = var.nic_security ? var.nic_security_group_ids : null - allowed_addresses = var.nic_security ? var.nic_allowed_addresses : null + network_id = stackit_network.this.network_id + + name = each.value.nic_name + ipv4 = each.value.nic_ipv4 + allowed_addresses = each.value.nic_allowed_addresses + labels = each.value.nic_labels + security = each.value.nic_security + security_group_ids = ( + each.value.nic_security_group_ids != null ? each.value.nic_security_group_ids : + each.value.nic_security_group_names != null ? + [for name in each.value.nic_security_group_names : var.security_group_ids_by_name[name]] + : [] + ) } + diff --git a/network/output.tf b/network/output.tf new file mode 100644 index 0000000..fc6e82d --- /dev/null +++ b/network/output.tf @@ -0,0 +1,9 @@ +output "network_id" { + description = "Network ID" + value = stackit_network.this.network_id +} + +output "network_name" { + description = "Network name" + value = stackit_network.this.name +} diff --git a/network/providers.tf b/network/providers.tf index 8962cf6..532c77d 100644 --- a/network/providers.tf +++ b/network/providers.tf @@ -1,10 +1,9 @@ - terraform { required_version = ">= 1.9.0" required_providers { stackit = { source = "stackitcloud/stackit" - version = "0.56.0" + version = "0.54.0" } } } diff --git a/network/variables.tf b/network/variables.tf index dd0dad5..68eb3a6 100644 --- a/network/variables.tf +++ b/network/variables.tf @@ -63,7 +63,7 @@ variable "no_ipv6_gateway" { variable "routed" { type = bool - default = true + # default = true } variable "nic_allowed_addresses" { @@ -97,7 +97,20 @@ variable "nic_security_group_ids" { default = [] } -variable "nic_security_group_names" { - type = list(string) - default = [] -} \ No newline at end of file +variable "nics" { + type = map(object({ + nic_ipv4 = optional(string) + nic_name = optional(string) + nic_allowed_addresses = optional(list(string)) + nic_labels = optional(map(string)) + nic_security = optional(bool) + nic_security_group_ids = optional(list(string)) + nic_security_group_names = optional(list(string)) + })) + default = {} +} + +variable "security_group_ids_by_name" { + description = "Map of security-group names -> IDs" + type = map(string) +} diff --git a/project/output.tf b/project/output.tf index 67fb6c5..09573a9 100644 --- a/project/output.tf +++ b/project/output.tf @@ -1,4 +1,4 @@ output "project_id" { - value = stackit_resourcemanager_project.this.id + value = stackit_resourcemanager_project.this.project_id description = "ID of the project" } \ No newline at end of file diff --git a/project/providers.tf b/project/providers.tf index 6e038c3..532c77d 100644 --- a/project/providers.tf +++ b/project/providers.tf @@ -3,7 +3,7 @@ terraform { required_providers { stackit = { source = "stackitcloud/stackit" - version = "0.56.0" + version = "0.54.0" } } } diff --git a/security-group/output.tf b/security-group/output.tf index b172314..d28e44e 100644 --- a/security-group/output.tf +++ b/security-group/output.tf @@ -1,8 +1,9 @@ output "security_group_id" { - value = stackit_security_group.this.security_group_id description = "ID of the security group" + value = stackit_security_group.this.security_group_id } -output "rule_ids" { - value = stackit_security_group_rule.rule[*].id +output "name" { + description = "Name of the security group" + value = stackit_security_group.this.name } diff --git a/security-group/providers.tf b/security-group/providers.tf index 6e038c3..532c77d 100644 --- a/security-group/providers.tf +++ b/security-group/providers.tf @@ -3,7 +3,7 @@ terraform { required_providers { stackit = { source = "stackitcloud/stackit" - version = "0.56.0" + version = "0.54.0" } } } diff --git a/security-group/variables.tf b/security-group/variables.tf index 4367b87..053a240 100644 --- a/security-group/variables.tf +++ b/security-group/variables.tf @@ -1,45 +1,107 @@ variable "project_id" { + description = "STACKIT project ID in which to create resources." type = string - description = "The ID of the project where the security group will be created." } variable "name" { + description = "Name of the network." type = string - description = "Name of the security group." } variable "description" { type = string default = "" - description = "Description of the security group. If not provided, it defaults to an empty string." +} + +variable "ipv4_gateway" { + description = "IPv4 gateway for the network. If null, the first IP in the CIDR is used." + type = string + nullable = true + default = null +} + +variable "ipv4_nameservers" { + description = "List of IPv4 nameservers." + type = list(string) + nullable = true + default = null +} + +variable "ipv4_prefix" { + description = "IPv4 prefix (CIDR) for the network." + type = string + nullable = true + default = null +} + +variable "ipv4_prefix_length" { + description = "IPv4 prefix length for the network." + type = number + nullable = true + default = null +} + +variable "ipv6_gateway" { + description = "IPv6 gateway for the network. If null, the first IP in the CIDR is used." + type = string + nullable = true + default = null +} + +variable "ipv6_nameservers" { + description = "List of IPv6 nameservers." + type = list(string) + nullable = true + default = null +} + +variable "ipv6_prefix" { + description = "IPv6 prefix (CIDR) for the network." + type = string + nullable = true + default = null +} + +variable "ipv6_prefix_length" { + description = "IPv6 prefix length for the network." + type = number + nullable = true + default = null +} + +variable "labels" { + description = "Key/value labels to attach to the network." + type = map(string) + nullable = true + default = null +} + +variable "no_ipv4_gateway" { + description = "If true, suppress creation of an IPv4 gateway." + type = bool + default = false +} + +variable "no_ipv6_gateway" { + description = "If true, suppress creation of an IPv6 gateway." + type = bool + default = false +} + +variable "routed" { + description = "If true, the network is routed." + type = bool + default = false +} + +variable "routing_table_id" { + description = "Routing table ID to associate with this network (experimental)." + type = string + nullable = true + default = null } variable "rules" { - description = "List of rules to attach to this security-group" - type = list(object({ - direction = string - description = optional(string) - ether_type = optional(string) - icmp_parameters = optional(object({ - type = optional(number) - code = optional(number) - })) - ip_range = optional(string) - port_range = optional(object({ - min = number - max = number - })) - protocol = optional(object({ - name = optional(string) - })) - remote_security_group_id = optional(string) - })) - default = [] - validation { - condition = alltrue([ - for rule in var.rules : contains(["ingress", "egress"], rule.direction) - # ... need more validations - ]) - error_message = "Direction must be either \"ingress\" or \"egress\"." - } + description = "List of routing rules to apply to this network (experimental)." + type = any }