-
Notifications
You must be signed in to change notification settings - Fork 2
feat: central/shared kubernetes platform landing zone and optional namespace creation in app landing zone #39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| ################### | ||
| ## OBSERVABILITY ## | ||
| ################### | ||
|
|
||
| resource "stackit_observability_instance" "this" { | ||
| count = var.observability.enabled ? 1 : 0 | ||
|
|
||
| project_id = stackit_resourcemanager_project.this.project_id | ||
| name = var.observability.name != null ? var.observability.name : "${var.naming_pattern}-obs" | ||
| plan_name = var.observability.plan_name | ||
| acl = var.observability.acl | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,4 +31,35 @@ output "connected_network_area_id" { | |
| output "landing_zone_type" { | ||
| description = "The type of the landing zone, either 'corporate' or 'public'." | ||
| value = var.corporate ? "corporate" : "public" | ||
| } | ||
|
|
||
| output "secretsmanager_instance_id" { | ||
| description = "The ID of the landing zone Secrets Manager instance." | ||
| value = stackit_secretsmanager_instance.this.instance_id | ||
| } | ||
|
|
||
| output "observability_instance_id" { | ||
| description = "The optional observability instance ID in the landing zone project." | ||
| value = var.observability.enabled ? stackit_observability_instance.this[0].instance_id : null | ||
| } | ||
|
|
||
| output "observability_grafana_url" { | ||
| description = "The Grafana URL of the optional landing zone observability instance." | ||
| value = var.observability.enabled ? stackit_observability_instance.this[0].grafana_url : null | ||
| } | ||
|
|
||
| output "observability_grafana_admin_user" { | ||
| description = "The initial Grafana admin user of the optional landing zone observability instance." | ||
| value = var.observability.enabled ? stackit_observability_instance.this[0].grafana_initial_admin_user : null | ||
| } | ||
|
|
||
| output "observability_grafana_admin_password" { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the user + password should not be an output since it will not be used later on in the terraform |
||
| description = "The initial Grafana admin password of the optional landing zone observability instance." | ||
| value = var.observability.enabled ? stackit_observability_instance.this[0].grafana_initial_admin_password : null | ||
| sensitive = true | ||
| } | ||
|
|
||
| output "observability_metrics_push_url" { | ||
| description = "The Prometheus remote-write URL of the optional landing zone observability instance." | ||
| value = var.observability.enabled ? stackit_observability_instance.this[0].metrics_push_url : null | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| locals { | ||
| project_labels = merge( | ||
| { "region" = var.region }, | ||
| var.network.mode == "sna" && var.network.sna_network_area_id != null ? { "networkArea" = var.network.sna_network_area_id } : {}, | ||
| var.labels | ||
| ) | ||
| } | ||
|
|
||
| resource "stackit_resourcemanager_project" "this" { | ||
| parent_container_id = var.parent_container_id | ||
| name = var.project_name != null ? var.project_name : var.naming_pattern | ||
| owner_email = var.owner_email | ||
| labels = length(local.project_labels) > 0 ? local.project_labels : null | ||
| } | ||
|
|
||
| resource "stackit_authorization_project_role_assignment" "this" { | ||
| for_each = { for assignment in var.role_assignments : "${assignment.role}-${assignment.subject}" => assignment } | ||
|
|
||
| resource_id = stackit_resourcemanager_project.this.project_id | ||
| role = each.value.role | ||
| subject = each.value.subject | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| locals { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would put 2-dns-zones.tf, 2-network-area-membership and 2-sna-network in one 2-network.tf |
||
| dns_extension_zones = distinct(compact(var.dns.zones)) | ||
| } | ||
|
|
||
| resource "stackit_dns_zone" "ske_extension" { | ||
| for_each = var.dns.create_zones ? { for zone in local.dns_extension_zones : zone => zone } : {} | ||
|
|
||
| project_id = stackit_resourcemanager_project.this.project_id | ||
| name = each.value | ||
| dns_name = each.value | ||
| contact_email = var.owner_email | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| resource "time_sleep" "wait_for_network_area_membership" { | ||
| count = var.network.mode == "sna" ? 1 : 0 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. input variable should be a boolean |
||
|
|
||
| # Allow backend propagation after project label updates before SKE SNA validation. | ||
| create_duration = "30s" | ||
|
|
||
| depends_on = [stackit_resourcemanager_project.this] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| resource "stackit_observability_instance" "this" { | ||
| count = var.observability.enabled ? 1 : 0 | ||
|
|
||
| project_id = stackit_resourcemanager_project.this.project_id | ||
| name = var.observability.name != null ? var.observability.name : "${var.naming_pattern}-obs" | ||
| plan_name = var.observability.plan_name | ||
| acl = var.observability.acl | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| resource "stackit_network" "sna" { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no routing table here. I´m assuming that even if it is connected to sna, the traffic will not go through the firewall but directly to the internet |
||
| count = local.use_sna ? 1 : 0 | ||
|
|
||
| project_id = stackit_resourcemanager_project.this.project_id | ||
| name = "${var.cluster.name}-sna" | ||
| ipv4_prefix_length = var.network.sna_network_prefix_length | ||
| routed = true | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| locals { | ||
| use_sna = lower(var.network.mode) == "sna" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this local is not neccessary if the input variable would be a boolean already eg "sna_enabled" also for the time_sleep resource this is used: count = var.network.mode == "sna" ? 1 : 0 which would fail for "SNA" anyway |
||
|
|
||
| effective_observability_instance_id = var.observability.enabled ? stackit_observability_instance.this[0].instance_id : null | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no local needed since the value is not reused, can be defined inline in line 65 --> local.effective_observability_instance_id |
||
| effective_dns_zones = var.dns.create_zones ? sort([ | ||
| for zone in values(stackit_dns_zone.ske_extension) : zone.dns_name | ||
| ]) : local.dns_extension_zones | ||
| default_node_pools = [ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the default_node_pools should go into the var.cluster variable as default |
||
| { | ||
| name = "ha-a" | ||
| machine_type = "g3i.4" | ||
| minimum = 2 | ||
| maximum = 2 | ||
| availability_zones = ["${var.region}-1"] | ||
| volume_size = 20 | ||
| volume_type = "storage_premium_perf1" | ||
| os_name = "flatcar" | ||
| labels = {} | ||
| }, | ||
| { | ||
| name = "ha-b" | ||
| machine_type = "g3i.4" | ||
| minimum = 2 | ||
| maximum = 2 | ||
| availability_zones = ["${var.region}-2"] | ||
| volume_size = 20 | ||
| volume_type = "storage_premium_perf1" | ||
| os_name = "flatcar" | ||
| labels = {} | ||
| } | ||
| ] | ||
| effective_node_pools = length(var.cluster.node_pools) > 0 ? var.cluster.node_pools : local.default_node_pools | ||
| } | ||
|
|
||
| resource "stackit_ske_cluster" "this" { | ||
| project_id = stackit_resourcemanager_project.this.project_id | ||
| region = var.region | ||
| name = var.cluster.name | ||
| depends_on = [time_sleep.wait_for_network_area_membership, stackit_dns_zone.ske_extension] | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. depends_on always at the bottom for readability: https://developer.hashicorp.com/terraform/language/style#resource-order |
||
| kubernetes_version_min = var.cluster.kubernetes_version_min | ||
| node_pools = local.effective_node_pools | ||
|
|
||
| maintenance = { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since all key value pairs are equal: maintenance = var.cluster.maintenance should work, no need for mapping |
||
| enable_kubernetes_version_updates = var.cluster.maintenance.enable_kubernetes_version_updates | ||
| enable_machine_image_version_updates = var.cluster.maintenance.enable_machine_image_version_updates | ||
| start = var.cluster.maintenance.start | ||
| end = var.cluster.maintenance.end | ||
| } | ||
|
|
||
| network = local.use_sna ? { | ||
| id = stackit_network.sna[0].network_id | ||
| control_plane = { | ||
| access_scope = "SNA" | ||
| } | ||
| } : { | ||
| id = null | ||
| control_plane = { | ||
| access_scope = "PUBLIC" | ||
| } | ||
| } | ||
|
|
||
| extensions = { | ||
| observability = { | ||
| enabled = var.observability.enabled | ||
| instance_id = local.effective_observability_instance_id | ||
| } | ||
| dns = { | ||
| enabled = var.dns.enabled && length(local.effective_dns_zones) > 0 | ||
| zones = local.effective_dns_zones | ||
| } | ||
| } | ||
| } | ||
|
|
||
| resource "stackit_ske_kubeconfig" "this" { | ||
| project_id = stackit_resourcemanager_project.this.project_id | ||
| region = var.region | ||
| cluster_name = stackit_ske_cluster.this.name | ||
|
|
||
| refresh = true | ||
| expiration = 7200 | ||
| refresh_before = 1800 | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| data "stackit_service_accounts" "ske_internal" { | ||
| count = var.encrypted_volumes.enabled ? 1 : 0 | ||
|
|
||
| project_id = stackit_resourcemanager_project.this.project_id | ||
| email_suffix = "@ske.sa.stackit.cloud" | ||
|
|
||
| depends_on = [stackit_ske_cluster.this] | ||
| } | ||
|
|
||
| resource "stackit_kms_keyring" "this" { | ||
| count = var.encrypted_volumes.enabled ? 1 : 0 | ||
|
|
||
| project_id = stackit_resourcemanager_project.this.project_id | ||
| display_name = "${var.naming_pattern}-${var.encrypted_volumes.kms_keyring_name}" | ||
| } | ||
|
|
||
| resource "stackit_kms_key" "this" { | ||
| count = var.encrypted_volumes.enabled ? 1 : 0 | ||
|
|
||
| project_id = stackit_resourcemanager_project.this.project_id | ||
| keyring_id = stackit_kms_keyring.this[0].keyring_id | ||
| display_name = "${var.naming_pattern}-${var.encrypted_volumes.kms_key_name}" | ||
| protection = "software" | ||
| algorithm = "aes_256_gcm" | ||
| purpose = "symmetric_encrypt_decrypt" | ||
| } | ||
|
|
||
| resource "stackit_service_account" "kms_manager" { | ||
| count = var.encrypted_volumes.enabled ? 1 : 0 | ||
|
|
||
| project_id = stackit_resourcemanager_project.this.project_id | ||
| # STACKIT service account names are limited to 20 characters. | ||
| name = "${substr(var.naming_pattern, 0, 8)}-kms-mgr" | ||
| } | ||
|
|
||
| resource "stackit_authorization_project_role_assignment" "kms_admin" { | ||
| count = var.encrypted_volumes.enabled ? 1 : 0 | ||
|
|
||
| resource_id = stackit_resourcemanager_project.this.project_id | ||
| role = "kms.admin" | ||
| subject = stackit_service_account.kms_manager[0].email | ||
| } | ||
|
|
||
| resource "stackit_authorization_service_account_role_assignment" "ske_impersonation" { | ||
| count = var.encrypted_volumes.enabled ? 1 : 0 | ||
|
|
||
| resource_id = stackit_service_account.kms_manager[0].service_account_id | ||
| role = "user" | ||
| subject = data.stackit_service_accounts.ske_internal[0].items[0].email | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for the other resources there is no suffix referencing the resource type, like -obs here. Maybe -general or -default or -common or no suffix