diff --git a/example/main.tf b/example/main.tf index 2d2fc0b..4799fb5 100644 --- a/example/main.tf +++ b/example/main.tf @@ -1,10 +1,18 @@ -module "security_groups" { - source = "../security-group" +module "project" { + source = "../project" + for_each = var.projects - for_each = var.security_groups + organization_id = each.value.organization_id + name = each.value.name - project_id = var.project_id - name = each.value.name - description = each.value.description - rules = each.value.rules -} \ No newline at end of file + description = each.value.description != null ? each.value.description : null + labels = each.value.labels != {} ? each.value.labels : {} + + owner_email = each.value.owner_email + + security_groups = each.value.security_groups + networks = each.value.networks + postgres_instances = each.value.postgres_instances + ske_clusters = each.value.ske_clusters + observability_instances = each.value.observability_instances +} diff --git a/example/providers.tf b/example/providers.tf index e5cfc8d..5eb9d92 100644 --- a/example/providers.tf +++ b/example/providers.tf @@ -9,7 +9,8 @@ terraform { } provider "stackit" { - default_region = var.region - service_account_token = var.service_account_token - enable_beta_resources = true + default_region = var.region + service_account_token = var.service_account_token != "" ? var.service_account_token : null + service_account_key_path = var.service_account_key_path != "" ? var.service_account_key_path : null + enable_beta_resources = true } \ No newline at end of file diff --git a/example/terraform.tfvars b/example/terraform.tfvars index 584af52..a9f8b5b 100644 --- a/example/terraform.tfvars +++ b/example/terraform.tfvars @@ -1,59 +1,186 @@ -region = "eu01" -service_account_token = "" -project_id = "" +region = "eu01" +service_account_key_path = "/Users/schlenz/sa-key-dd5fa2c9-1651-4da7-8404-9ac4fe9bc3d5.json" -security_groups = { - ssh_ingress_group = { - name = "ssh-ingress-group" - description = "ALLOW SSH ingress" - rules = [ - { - description = "SSH RULE 1" - direction = "ingress" - ether_type = "IPv4" - ip_range = "0.0.0.0/0" - protocol = { - name = "tcp" +projects = { + project_1 = { + name = "project-1" + organization_id = "03a34540-3c1a-4794-b2c6-7111ecf824ef" + owner_email = "maximilian.schlenz@stackit.cloud" + + postgres_instances = { + dev = { + name = "pg-test-instance" + version = 17 + flavor = { + cpu = 2, + ram = 4 } - port_range = { - min = 22 - max = 22 + storage = { + class = "premium-perf6-stackit", + size = 20 } - }, - ] + replicas = 1 + acl = ["0.0.0.0/0"] + backup_schedule = "00 00 * * *" + + users = [ + { username = "adm-usr", + roles = ["login", "createdb"] + }, + { username = "testusr", + roles = ["login"] + } + ] + + databases = [ + { + name = "test-db", + owner = "admin" + } + ] + } + } + + networks = { + tiny = { + name = "tiny-net" + ipv4_prefix_length = 28 + labels = { + purpose = "test" + } + security_groups = { + ssh_ingress_group = { + name = "ssh-ingress-group" + description = "ALLOW SSH ingress" + rules = [ + { description = "SSH RULE 1" + direction = "ingress" + ether_type = "IPv4" + ip_range = "0.0.0.0/0" + protocol = { + name = "tcp" + } + port_range = { + min = 22 + max = 23 + } + }, + ] + }, + + web_traffic_group = { + name = "web-traffic-group" + description = "ALLOW WEB TRAFFIC ingress" + rules = [ + { description = "ALLOW ALL 80" + direction = "ingress" + ether_type = "IPv4" + ip_range = "0.0.0.0/0" + protocol = { + name = "tcp" + } + port_range = { + min = 80 + max = 80 + } + }, + { description = "ALLOW ALL 443" + direction = "ingress" + ether_type = "IPv4" + ip_range = "0.0.0.0/0" + protocol = { + name = "tcp" + } + port_range = { + min = 443 + max = 443 + } + }, + ] + }, + } + network_static = { + } + + custom_static = { + name = "static-net" + routed = true + ipv4_prefix = "10.99.0.0/24" + ipv4_gateway = "10.99.0.1" + + nic_ipv4 = "10.99.0.10" + nic_name = "static-nic" + nic_security_group_ids = [""] + } + } + } + + # ske_clusters = { + # dev = { + # name = "dev" + # kubernetes_version_min = "1.31" + # node_pools = [ + # { name = "default" + # machine_type = "c2.1" + # availability_zones = ["eu01-1", "eu01-2"] + # volume_size = 40 + # minimum = 1 + # maximum = 3 + # } + # ] + # } + + # prod = { + # name = "prod" + # kubernetes_version_min = "1.31" + # node_pools = [ + # { name = "general" + # machine_type = "c2.2" + # availability_zones = ["eu03-1", "eu03-2"] + # volume_size = 80 + # minimum = 2 + # maximum = 4 + # } + # ] + # } + # } + + observability_instances = { + starter = { + name = "Observability-1" + plan_name = "Observability-Starter-EU01" + } + + prod = { + name = "Observability-2" + plan_name = "Observability-Large-EU01" + } + } + }, + # project_2 = { + # name = "project-2" + # organization_id = "03a34540-3c1a-4794-b2c6-7111ecf824ef" + # owner_email = "maximilian.schlenz@stackit.cloud" + # networks = { + # tiny = { + # name = "tiny-net" + # ipv4_prefix_length = 28 + # labels = { + # purpose = "test" + # } + # } - web_traffic_group = { - name = "web-traffic-group" - description = "ALLOW WEB TRAFFIC ingress" - rules = [ - { - description = "ALLOW ALL 80" - direction = "ingress" - ether_type = "IPv4" - ip_range = "0.0.0.0/0" - protocol = { - name = "tcp" - } - port_range = { - min = 80 - max = 80 - } - }, - { - description = "ALLOW ALL 443" - direction = "ingress" - ether_type = "IPv4" - ip_range = "0.0.0.0/0" - protocol = { - name = "tcp" - } - port_range = { - min = 443 - max = 443 - } - }, - ] - }, + # custom_static = { + # name = "static-net" + # routed = false + # ipv4_prefix = "10.99.0.0/24" + # ipv4_gateway = "10.99.0.1" + # nic_ipv4 = "10.99.0.10" + # nic_name = "static-nic" + # nic_security_group_ids = [""] + # } + # } + # } } \ No newline at end of file diff --git a/example/variables.tf b/example/variables.tf index 918e44e..8bbd19a 100644 --- a/example/variables.tf +++ b/example/variables.tf @@ -4,40 +4,111 @@ variable "region" { default = "eu01" } -variable "project_id" { - description = "STACKIT Cloud project ID" - type = string -} - variable "service_account_token" { description = "Service account token for authentication" sensitive = true type = string + default = "" } +variable "service_account_key_path" { + type = string + default = "" +} -variable "security_groups" { +variable "projects" { type = map(object({ - name = optional(string) - description = optional(string) - rules = list(object({ - direction = string + + organization_id = string + name = string + description = optional(string) + labels = optional(map(string)) + project_id = optional(string) + owner_email = optional(string) + + security_groups = optional(map(object({ + name = string description = optional(string) - ether_type = optional(string) - icmp_parameters = optional(object({ - type = optional(number) - code = optional(number) + rules = list(object({ + description = optional(string) + direction = string + ether_type = optional(string) + ip_range = optional(string) + protocol = optional(object({ + name = optional(string) + number = optional(number) + })) + port_range = optional(object({ + min = number + max = number + })) + remote_security_group_id = optional(string) })) - ip_range = optional(string) - port_range = optional(object({ - min = number - max = number + })), {}) + + networks = optional(map(object({ + name = string + ipv4_gateway = optional(string) + ipv4_nameservers = optional(list(string)) + ipv4_prefix = optional(string) + ipv4_prefix_length = optional(number) + ipv6_gateway = optional(string) + ipv6_nameservers = optional(list(string)) + ipv6_prefix = optional(string) + ipv6_prefix_length = optional(number) + labels = optional(map(string)) + no_ipv4_gateway = optional(bool) + no_ipv6_gateway = optional(bool) + routed = optional(bool) + + 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)) + })), {}) + + postgres_instances = optional(map(object({ + name = string + version = number + flavor = object({ + cpu = number, + ram = number + }) + storage = object({ + class = string, + size = number + }) + replicas = number + acl = list(string) + backup_schedule = string + users = list(object({ + username = string + roles = set(string) })) - protocol = optional(object({ - name = optional(string) - number = optional(number) + databases = list(object({ + name = string + owner = string })) - remote_security_group_id = optional(string) - })) + })), {}) + + ske_clusters = optional(map(object({ + name = string + kubernetes_version_min = string + node_pools = list(object({ + name = string + machine_type = string + availability_zones = list(string) + volume_size = number + minimum = number + maximum = number + })) + })), {}) + + observability_instances = optional(map(object({ + name = string + plan_name = string + })), {}) })) } diff --git a/project/main.tf b/project/main.tf index 58176f0..1a4ee07 100644 --- a/project/main.tf +++ b/project/main.tf @@ -1,34 +1,79 @@ -variable "projects" { - type = map(object({ - name = string - owner_email = string - })) - default = { - project1 = { - name = "project-alpha" - owner_email = "michael.sodan@stackit.cloud" - } - project2 = { - name = "project-beta" - owner_email = "michael.sodan@stackit.cloud" - } - } +resource "stackit_resourcemanager_project" "this" { + parent_container_id = var.organization_id + name = var.name + labels = var.labels + owner_email = var.owner_email } -resource "stackit_resourcemanager_project" "projects" { - for_each = var.projects - parent_container_id = var.organization_id # Nutzt jetzt die übergebene Variable - name = each.value.name - owner_email = each.value.owner_email - # labels = { ... } # Vorerst entfernt, da stackit_network_area nicht definiert war +module "sg" { + source = "../security-group" + for_each = var.security_groups + + project_id = stackit_resourcemanager_project.this.project_id + name = each.value.name + description = each.value.description + rules = each.value.rules } -output "project_info" { - value = { - for k, project in stackit_resourcemanager_project.projects : k => { - project_id = project.project_id - container_id = project.container_id - } - } +module "net" { + source = "../network" + for_each = var.networks + + project_id = stackit_resourcemanager_project.this.project_id + name = each.value.name + + ipv4_gateway = each.value.ipv4_gateway != null ? each.value.ipv4_gateway : null + ipv4_nameservers = each.value.ipv4_nameservers != [] ? each.value.ipv4_nameservers : [] + ipv4_prefix = each.value.ipv4_prefix != null ? each.value.ipv4_prefix : null + ipv4_prefix_length = each.value.ipv4_prefix_length != null ? each.value.ipv4_prefix_length : null + ipv6_gateway = each.value.ipv6_gateway != null ? each.value.ipv6_gateway : null + ipv6_nameservers = each.value.ipv6_nameservers != [] ? each.value.ipv6_nameservers : [] + ipv6_prefix = each.value.ipv6_prefix != null ? each.value.ipv6_prefix : null + ipv6_prefix_length = each.value.ipv6_prefix_length != null ? each.value.ipv6_prefix_length : null + labels = each.value.labels != {} ? each.value.labels : {} + no_ipv4_gateway = each.value.no_ipv4_gateway + no_ipv6_gateway = each.value.no_ipv6_gateway + routed = each.value.routed != null ? each.value.routed : true + + nic_ipv4 = each.value.nic_ipv4 + nic_name = each.value.nic_name != null ? each.value.nic_name : null + nic_allowed_addresses = each.value.nic_allowed_addresses + nic_labels = each.value.nic_labels != {} ? each.value.nic_labels : {} + nic_security = each.value.nic_security + nic_security_group_ids = each.value.nic_security_group_ids } +module "pg" { + source = "../postgres" + for_each = var.postgres_instances + + project_id = stackit_resourcemanager_project.this.project_id + name = each.value.name + ver = each.value.version + flavor = each.value.flavor + storage = each.value.storage + replicas = each.value.replicas + acl = each.value.acl + backup_schedule = each.value.backup_schedule + users = each.value.users + databases = each.value.databases +} + +module "ske" { + source = "../ske" + for_each = var.ske_clusters + + project_id = stackit_resourcemanager_project.this.project_id + name = each.value.name + kubernetes_version_min = each.value.kubernetes_version_min + node_pools = each.value.node_pools +} + +module "obs" { + source = "../observability" + for_each = var.observability_instances + + project_id = stackit_resourcemanager_project.this.project_id + name = each.value.name + plan_name = each.value.plan_name +} diff --git a/project/output.tf b/project/output.tf new file mode 100644 index 0000000..e69de29 diff --git a/project/providers.tf b/project/providers.tf new file mode 100644 index 0000000..6e038c3 --- /dev/null +++ b/project/providers.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9.0" + required_providers { + stackit = { + source = "stackitcloud/stackit" + version = "0.56.0" + } + } +} diff --git a/project/variables.tf b/project/variables.tf index 6a8400f..75b7298 100644 --- a/project/variables.tf +++ b/project/variables.tf @@ -1,10 +1,140 @@ variable "organization_id" { - description = "Empfängt die Container-ID der Organisation vom Root-Modul." - type = string + type = string } -variable "sna_net" { - description = "SNA Transfer Network" - type = string +variable "name" { + type = string } +variable "description" { + type = string + default = null +} + +variable "labels" { + type = map(string) + default = {} +} + +variable "project_id" { + type = string + default = null +} + +variable "owner_email" { + type = string + default = null +} + +variable "security_groups" { + type = map(object({ + name = string + description = optional(string) + labels = optional(map(string)) + stateful = optional(bool) + rules = list(object({ + description = optional(string) + direction = string + ether_type = optional(string) + ip_range = optional(string) + protocol = optional(object({ + name = optional(string) + number = optional(number) + })) + port_range = optional(object({ + min = number + max = number + })) + remote_security_group_id = optional(string) + })) + })) + default = {} +} + +variable "networks" { + type = map(object({ + name = string + ipv4_gateway = optional(string) + ipv4_nameservers = optional(list(string)) + ipv4_prefix = optional(string) + ipv4_prefix_length = optional(number) + ipv6_gateway = optional(string) + ipv6_nameservers = optional(list(string)) + ipv6_prefix = optional(string) + ipv6_prefix_length = optional(number) + labels = optional(map(string)) + no_ipv4_gateway = optional(bool) + no_ipv6_gateway = optional(bool) + routed = optional(bool) + + 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)) + })) + default = {} +} + +variable "postgres_instances" { + type = map(object({ + acl = list(string) + backup_schedule = string + + flavor = object({ + cpu = number + ram = number + }) + + name = string + replicas = number + + storage = object({ + class = string + size = number + }) + + version = string + region = optional(string) + + databases = optional(list(object({ + instance_id = optional(string) + name = string + owner = string + region = optional(string) + }))) + + users = optional(list(object({ + instance_id = optional(string) + roles = set(string) + username = string + region = optional(string) + }))) + })) + default = {} +} + +variable "ske_clusters" { + type = map(object({ + name = string + kubernetes_version_min = string + node_pools = list(object({ + name = string + machine_type = string + availability_zones = list(string) + volume_size = number + minimum = number + maximum = number + })) + })) + default = {} +} + +variable "observability_instances" { + type = map(object({ + name = string + plan_name = string + })) + default = {} +} diff --git a/project_old/main.tf b/project_old/main.tf new file mode 100644 index 0000000..58176f0 --- /dev/null +++ b/project_old/main.tf @@ -0,0 +1,34 @@ +variable "projects" { + type = map(object({ + name = string + owner_email = string + })) + default = { + project1 = { + name = "project-alpha" + owner_email = "michael.sodan@stackit.cloud" + } + project2 = { + name = "project-beta" + owner_email = "michael.sodan@stackit.cloud" + } + } +} + +resource "stackit_resourcemanager_project" "projects" { + for_each = var.projects + parent_container_id = var.organization_id # Nutzt jetzt die übergebene Variable + name = each.value.name + owner_email = each.value.owner_email + # labels = { ... } # Vorerst entfernt, da stackit_network_area nicht definiert war +} + +output "project_info" { + value = { + for k, project in stackit_resourcemanager_project.projects : k => { + project_id = project.project_id + container_id = project.container_id + } + } +} + diff --git a/project/provider.tf b/project_old/provider.tf similarity index 100% rename from project/provider.tf rename to project_old/provider.tf diff --git a/project/sna.tf b/project_old/sna.tf similarity index 100% rename from project/sna.tf rename to project_old/sna.tf diff --git a/project_old/variables.tf b/project_old/variables.tf new file mode 100644 index 0000000..6a8400f --- /dev/null +++ b/project_old/variables.tf @@ -0,0 +1,10 @@ +variable "organization_id" { + description = "Empfängt die Container-ID der Organisation vom Root-Modul." + type = string +} + +variable "sna_net" { + description = "SNA Transfer Network" + type = string +} + diff --git a/ske/main.tf b/ske/main.tf new file mode 100644 index 0000000..90124a0 --- /dev/null +++ b/ske/main.tf @@ -0,0 +1,12 @@ +resource "stackit_ske_cluster" "this" { + project_id = var.project_id + name = var.name + kubernetes_version_min = var.kubernetes_version_min + node_pools = var.node_pools +} + +resource "stackit_ske_kubeconfig" "admin" { + project_id = var.project_id + cluster_name = stackit_ske_cluster.this.name + refresh = true +} diff --git a/ske/output.tf b/ske/output.tf new file mode 100644 index 0000000..9abc2e4 --- /dev/null +++ b/ske/output.tf @@ -0,0 +1,10 @@ +output "name" { + description = "Name of SKE cluster" + value = stackit_ske_cluster.this.name +} + +output "kubeconfig" { + description = "Kubeconfig of SKE cluster" + value = stackit_ske_kubeconfig.admin.kube_config + sensitive = true +} \ No newline at end of file diff --git a/ske/providers.tf b/ske/providers.tf new file mode 100644 index 0000000..6e038c3 --- /dev/null +++ b/ske/providers.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9.0" + required_providers { + stackit = { + source = "stackitcloud/stackit" + version = "0.56.0" + } + } +} diff --git a/ske/variables.tf b/ske/variables.tf new file mode 100644 index 0000000..53533c0 --- /dev/null +++ b/ske/variables.tf @@ -0,0 +1,22 @@ +variable "project_id" { + type = string +} + +variable "name" { + type = string +} + +variable "kubernetes_version_min" { + type = string +} + +variable "node_pools" { + type = list(object({ + name = string + machine_type = string + availability_zones = list(string) + volume_size = number + minimum = number + maximum = number + })) +}