diff --git a/.github/workflows/default-ci.yaml b/.github/workflows/default-ci.yaml index 75355ad..7f9f84d 100644 --- a/.github/workflows/default-ci.yaml +++ b/.github/workflows/default-ci.yaml @@ -1,4 +1,4 @@ -name: "Professional Services CI" +name: "Default CI" on: push: @@ -17,6 +17,23 @@ jobs: - name: TruffleHog Scan uses: edplato/trufflehog-actions-scan@master + todo-check: + name: "Check for Open TODOs" + runs-on: ${{ github.server_url == 'https://github.com' && 'ubuntu-latest' || 'stackit-ubuntu-22' }} + steps: + - name: Checkout Code + uses: actions/checkout@v6 + + - name: Search codebase + run: | + # Searches recursively (-r), showing line numbers (-n), ignoring binary files (-I) + # Excludes the .git directory to prevent false positives + if grep -rnIE "# ?TODO" --exclude-dir=.git --exclude-dir=.github .; then + echo "Error: TODOs found in the codebase. Please resolve them before merging." + exit 1 + fi + echo "No TODOs found. Proceeding." + pre-commit-checks: name: "Pre-Commit Hooks" runs-on: ${{ github.server_url == 'https://github.com' && 'ubuntu-latest' || 'stackit-ubuntu-22' }} diff --git a/.github/workflows/github-mirror-ci.yaml b/.github/workflows/github-mirror-ci.yaml index c596648..de61ea9 100644 --- a/.github/workflows/github-mirror-ci.yaml +++ b/.github/workflows/github-mirror-ci.yaml @@ -28,11 +28,11 @@ jobs: - name: Push to Public Repo run: | echo "Setting up remote..." - git config --global user.name "prof-service-sync-bot" - git config --global user.email "prof-service-sync-bot@digits.schwarz" + git config --global user.name "ps-sync-bot" + git config --global user.email "ps-sync-bot@digits.schwarz" # Add the GitHub remote using the SSH protocol - git remote add public git@github.com:stackitcloud/professional-services.git + git remote add public git@github.com:stackitcloud/professional-service.git echo "Pushing main branch to GitHub..." git push public main --force diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 0000000..8b1c7fc --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,41 @@ +# Project Governance: STACKIT Professional Service + +This document defines the management, ownership, and maintenance processes for the STACKIT Professional Service repository. + +## 1. Strategy & "The Story" + +This repository serves as a bridge between internal excellence and public visibility. + +- **Internal Git (Source of Truth):** The primary repository is hosted on our internal STACKIT Git instance. All internal communication, documentation, and chat links MUST point to the internal instance to promote our own infrastructure and tools. +- **GitHub (Public Mirror):** The GitHub repository is a mirror intended for external visibility, SEO, and accessibility for AI models (LLMs). It helps customers find our solutions and establishes STACKIT as a thought leader in cloud automation. + +## 2. Ownership + +### 2.1 Organizational Ownership + +The repository is owned by the **STACKIT Professional Services** organization. High-level decisions regarding repository structure, licensing, and global policies are managed by the Core Maintainers team. + +### 2.2 Example & Module Ownership + +Individual examples or modules within the repository have specific owners, documented in their respective `MAINTAINERS.md` files. + +- **Responsibility:** Owners are responsible for the technical health, periodic updates (e.g., dependency bumps), and community feedback for their specific content. +- **Handover:** If an owner leaves the project or company, ownership reverts to the Core Maintainers until a new owner is assigned. + +## 3. Review & Quality Assurance + +To ensure high standards and security, we follow a strict contribution process: + +- **4-Eyes Principle:** No code enters the `main` branch without at least one successful Peer Review. +- **Automated Validation:** Every Pull Request must pass the CI pipeline, which includes: + - Linting and formatting checks. + - License header verification (Apache 2.0). + - Secret scanning (Trufflehog). +- **Best Effort Policy:** While we strive for quality, the content is provided "as-is." Use in production environments requires independent validation by the user. + +## 4. Mirroring Process + +The synchronization between the internal Git and GitHub is fully automated: + +1. Changes are merged into the internal `main` branch. +2. A GitHub Action triggers on every push to `main`. diff --git a/README.md b/README.md index 46e3b56..9fce77a 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,12 @@ -# STACKIT Professional Services +# STACKIT Professional Service -Welcome to the central repository for STACKIT Professional Services examples, scripts, and boilerplate code! +Welcome to the central repository for STACKIT examples, scripts, and boilerplate code! > **⚠️ REPOSITORY MIRROR NOTICE** > > This GitHub repository is a **mirror**. > The primary, internal source of truth for this codebase lives at: -> `https://professional-service.git.onstackit.cloud/professional-service-best-practices/professional-services` +> `https://professional-service.git.onstackit.cloud/professional-service-best-practices/professional-service` > > We automatically sync changes from our STACKIT managed GIT instance to this public GitHub repository. > @@ -20,7 +20,7 @@ Let's be upfront about how this repository is maintained: - **Strictly Best Effort:** Everything you find in this repository is provided on a "best effort" basis. - **No Guarantees on Freshness:** We try our best to keep the examples, Terraform modules, and scripts up to date with the latest provider releases and API changes. However, **we cannot guarantee it**. Things move fast in the cloud, and some examples might become outdated over time. -- **Use Your Brain:** Do not blindly copy-paste code from here directly into a production environment. +- **Review Before Deploying:** Do not blindly copy-paste code from here directly into a production environment. ## Contents diff --git a/examples/dbaas-otel-collect-metrics/.terraform.lock.hcl b/examples/dbaas-otel-collect-metrics/.terraform.lock.hcl new file mode 100644 index 0000000..810732d --- /dev/null +++ b/examples/dbaas-otel-collect-metrics/.terraform.lock.hcl @@ -0,0 +1,107 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/helm" { + version = "3.1.1" + hashes = [ + "h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=", + "h1:5b2ojWKT0noujHiweCds37ZreRFRQLNaErdJLusJN88=", + "zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275", + "zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a", + "zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29", + "zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104", + "zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990", + "zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34", + "zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8", + "zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1", + "zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b", + "zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903", + "zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "3.1.0" + constraints = ">= 2.14.0" + hashes = [ + "h1:G9QqKNpcztBRqrywtlNylFJSpGzDfRFtO8hcWLdkvRY=", + "h1:oodIAuFMikXNmEtil5MQgP4dfSctUBYQiGJfjbsF3NY=", + "zh:0215c5c60be62028c09a2f22458e89cda3ef5830a632299f1d401eb3538874b0", + "zh:09ebb9f442431e278a310a9423f32caf467cb4b3cad3fe59573ca71fa7b14e20", + "zh:0c4e5912f83bb35846ae0a9ae54fc320706ee61894cd21cc6b4181b1c5a2fa5c", + "zh:1678c982853ad461e65ccb5e79d585e13ed109dd47dab2a66d3a7a304faeef65", + "zh:1c050a5c15e330457a9c18caacf61a923c59d663e13f2962e4b32f04fef523a0", + "zh:2c55bcec83be58ec132c7cb0a1ac644758b800d794fdc636d53a0eada0358a3a", + "zh:a062bb0aa316c08d8460c66a5d68da71da40de5d3bc3b31abcf3a1a9a19650f1", + "zh:a26fdea0afaa9b247c73c0b42843ca51ba7db0ac2571f9d3d50dcabd20ca1b98", + "zh:c872c9385a78d502bf5823d61cd3bb0f9a0585030e025eb12585c83451beeaa1", + "zh:f180879af931182beee4c8c0d9dab62b81d86f17ddcbe3786ef4c7cec9163a4e", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f70f5789264069e0eef06f9b5d5fde955ef7206f7d446d1ce51a4c37a3f3e02f", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.8.1" + constraints = ">= 3.6.3" + hashes = [ + "h1:Eexl06+6J+s75uD46+WnZtpJZYRVUMB0AiuPBifK6Jc=", + "h1:u8AKlWVDTH5r9YLSeswoVEjiY72Rt4/ch7U+61ZDkiQ=", + "zh:08dd03b918c7b55713026037c5400c48af5b9f468f483463321bd18e17b907b4", + "zh:0eee654a5542dc1d41920bbf2419032d6f0d5625b03bd81339e5b33394a3e0ae", + "zh:229665ddf060aa0ed315597908483eee5b818a17d09b6417a0f52fd9405c4f57", + "zh:2469d2e48f28076254a2a3fc327f184914566d9e40c5780b8d96ebf7205f8bc0", + "zh:37d7eb334d9561f335e748280f5535a384a88675af9a9eac439d4cfd663bcb66", + "zh:741101426a2f2c52dee37122f0f4a2f2d6af6d852cb1db634480a86398fa3511", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:a902473f08ef8df62cfe6116bd6c157070a93f66622384300de235a533e9d4a9", + "zh:b85c511a23e57a2147355932b3b6dce2a11e856b941165793a0c3d7578d94d05", + "zh:c5172226d18eaac95b1daac80172287b69d4ce32750c82ad77fa0768be4ea4b8", + "zh:dab4434dba34aad569b0bc243c2d3f3ff86dd7740def373f2a49816bd2ff819b", + "zh:f49fd62aa8c5525a5c17abd51e27ca5e213881d58882fd42fec4a545b53c9699", + ] +} + +provider "registry.terraform.io/hashicorp/time" { + version = "0.13.1" + hashes = [ + "h1:+W+DMrVoVnoXo3f3M4W+OpZbkCrUn6PnqDF33D2Cuf0=", + "h1:ZT5ppCNIModqk3iOkVt5my8b8yBHmDpl663JtXAIRqM=", + "zh:02cb9aab1002f0f2a94a4f85acec8893297dc75915f7404c165983f720a54b74", + "zh:04429b2b31a492d19e5ecf999b116d396dac0b24bba0d0fb19ecaefe193fdb8f", + "zh:26f8e51bb7c275c404ba6028c1b530312066009194db721a8427a7bc5cdbc83a", + "zh:772ff8dbdbef968651ab3ae76d04afd355c32f8a868d03244db3f8496e462690", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:898db5d2b6bd6ca5457dccb52eedbc7c5b1a71e4a4658381bcbb38cedbbda328", + "zh:8de913bf09a3fa7bedc29fec18c47c571d0c7a3d0644322c46f3aa648cf30cd8", + "zh:9402102c86a87bdfe7e501ffbb9c685c32bbcefcfcf897fd7d53df414c36877b", + "zh:b18b9bb1726bb8cfbefc0a29cf3657c82578001f514bcf4c079839b6776c47f0", + "zh:b9d31fdc4faecb909d7c5ce41d2479dd0536862a963df434be4b16e8e4edc94d", + "zh:c951e9f39cca3446c060bd63933ebb89cedde9523904813973fbc3d11863ba75", + "zh:e5b773c0d07e962291be0e9b413c7a22c044b8c7b58c76e8aa91d1659990dfb5", + ] +} + +provider "registry.terraform.io/stackitcloud/stackit" { + version = "0.92.0" + constraints = ">= 0.87.0" + hashes = [ + "h1:dE5sdzUaHkzVL8AW3+GXD2EEWX2PlS+sHT7F25SXcZ0=", + "h1:j26ncxqlAp4q0/NHFoiATuVdIg7KH0zZhWoSAd+4Yj0=", + "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", + "zh:5eaa713f68a004ec33697f510ca4c7722940e2bab8080c025822ca547325ef98", + "zh:60ed4496492b9781f7cc581e346222a6356538a527e4ac67dce6815a64fc5c66", + "zh:6834a7819429e3482a5fdd547c442cc032d7047c3fb0dee30e8babb2438598e1", + "zh:6de632db0cbb42b429a9e752078df37716b0f335e5c39e883be5c55f7f1da553", + "zh:ac8b1bc8212236aaab789cef1dce718e6b8394bcf4b5f6c6f8dabf8c8a213573", + "zh:af4b1e805d6082a3ec94d2f5b68e8a62f04205af3f75a4a7d1b167e0f027d9ec", + "zh:b709258a4cd3acd0a9426809c1d7c1ed25859010b566c1b29481b132a7e2af13", + "zh:c7e8c5e8f2ca8c14c1bf5c92716a761b67792b38046b99653bdbf9ca423fc675", + "zh:c7f47c6b7e33d1f28bdc8d1aa5fda2734d74d6b1b0c6ef8b258489d9405af231", + "zh:d57dc6ad6b3a2879aa47012faf82f597a2ca1c3de1561bb96c6191e65072ea95", + "zh:d5b18390104164477913ced864e7a1cd5a678490f9412be887e5d8e3961d242e", + "zh:ead616306ab18c30a4c1110ad7fa8aee7d8a99e4410ceecbe5875beac5724f8a", + "zh:f73ad70183a35e5d04e4b48c44654c76fec48a8f4c913dd31a5befc2a1c2e4dc", + ] +} diff --git a/examples/dbaas-otel-collect-metrics/00-provider.tf b/examples/dbaas-otel-collect-metrics/00-provider.tf new file mode 100644 index 0000000..8bf8bc1 --- /dev/null +++ b/examples/dbaas-otel-collect-metrics/00-provider.tf @@ -0,0 +1,55 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file defines the required Terraform providers and their configurations. +# It sets up the STACKIT, Kubernetes, and Helm providers to manage resources in the project and the SKE cluster. +terraform { + required_version = ">= 0.14.0" + required_providers { + stackit = { + source = "stackitcloud/stackit" + version = ">= 0.87.0" + } + random = { + source = "hashicorp/random" + version = ">= 3.6.3" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = ">=2.14.0" + } + } +} + +provider "stackit" { + default_region = var.stackit_region + service_account_key_path = var.stackit_service_account_key_path + experiments = ["iam"] +} + +provider "kubernetes" { + host = yamldecode(stackit_ske_kubeconfig.this.kube_config).clusters.0.cluster.server + client_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.this.kube_config).users.0.user.client-certificate-data) + client_key = base64decode(yamldecode(stackit_ske_kubeconfig.this.kube_config).users.0.user.client-key-data) + cluster_ca_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.this.kube_config).clusters.0.cluster.certificate-authority-data) +} + +provider "helm" { + kubernetes = { + host = yamldecode(stackit_ske_kubeconfig.this.kube_config).clusters.0.cluster.server + client_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.this.kube_config).users.0.user.client-certificate-data) + client_key = base64decode(yamldecode(stackit_ske_kubeconfig.this.kube_config).users.0.user.client-key-data) + cluster_ca_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.this.kube_config).clusters.0.cluster.certificate-authority-data) + } +} diff --git a/examples/dbaas-otel-collect-metrics/01-variables.tf b/examples/dbaas-otel-collect-metrics/01-variables.tf new file mode 100644 index 0000000..35ec61c --- /dev/null +++ b/examples/dbaas-otel-collect-metrics/01-variables.tf @@ -0,0 +1,33 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +variable "stackit_project_id" { + type = string + default = "d75e6aab-b616-4b42-ae3b-aaf161ad626d" +} + +variable "stackit_region" { + type = string + default = "eu01" +} + +variable "stackit_service_account_key_path" { + type = string + default = "../../keys/stackit-sa.json" +} + +resource "stackit_key_pair" "admin_keypair" { + name = "admin-keypair-12345" + public_key = chomp(file("~/.ssh/id_rsa.pub")) +} diff --git a/examples/dbaas-otel-collect-metrics/02-ske.tf b/examples/dbaas-otel-collect-metrics/02-ske.tf new file mode 100644 index 0000000..173ccbb --- /dev/null +++ b/examples/dbaas-otel-collect-metrics/02-ske.tf @@ -0,0 +1,67 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +resource "stackit_ske_kubeconfig" "this" { + project_id = var.stackit_project_id + cluster_name = stackit_ske_cluster.this.name + refresh = true + + depends_on = [stackit_ske_cluster.this] +} + +data "stackit_ske_kubernetes_versions" "this" { + version_state = "SUPPORTED" +} + +data "stackit_ske_machine_image_versions" "this" { + version_state = "SUPPORTED" +} + +locals { + flatcar_supported_version = one(flatten([ + for mi in data.stackit_ske_machine_image_versions.this.machine_images : [ + for v in mi.versions : + v.version + if mi.name == "flatcar" + ] + ])) +} + +resource "stackit_ske_cluster" "this" { + project_id = var.stackit_project_id + name = "dbaas-otel" + kubernetes_version_min = data.stackit_ske_kubernetes_versions.this.kubernetes_versions.0.version + + maintenance = { + enable_kubernetes_version_updates = true + enable_machine_image_version_updates = true + start = "01:00:00Z" + end = "02:00:00Z" + } + + node_pools = [ + { + name = "standard" + machine_type = "g2i.4" + minimum = "3" + maximum = "9" + max_surge = "3" + availability_zones = ["eu01-1", "eu01-2", "eu01-3"] + os_version_min = local.flatcar_supported_version + os_name = "flatcar" + volume_size = 150 + volume_type = "storage_premium_perf6" + }, + ] +} diff --git a/examples/dbaas-otel-collect-metrics/03-observability.tf b/examples/dbaas-otel-collect-metrics/03-observability.tf new file mode 100644 index 0000000..916d7db --- /dev/null +++ b/examples/dbaas-otel-collect-metrics/03-observability.tf @@ -0,0 +1,20 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +resource "stackit_observability_instance" "example" { + project_id = var.stackit_project_id + name = "example-obs" + plan_name = "Observability-Large-EU01" + alert_config = null +} diff --git a/examples/dbaas-otel-collect-metrics/04-postgres.tf b/examples/dbaas-otel-collect-metrics/04-postgres.tf new file mode 100644 index 0000000..6247083 --- /dev/null +++ b/examples/dbaas-otel-collect-metrics/04-postgres.tf @@ -0,0 +1,44 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +resource "stackit_postgresflex_instance" "this" { + project_id = var.stackit_project_id + name = "example-instance" + backup_schedule = "00 00 * * *" + flavor = { + cpu = 2 + ram = 4 + } + replicas = 3 + storage = { + class = "premium-perf2-stackit" + size = 15 + } + version = 15 + acl = ["0.0.0.0/0"] +} + +resource "stackit_postgresflex_user" "this" { + project_id = var.stackit_project_id + instance_id = stackit_postgresflex_instance.this.instance_id + username = "test" + roles = ["createdb", "login"] +} + +resource "stackit_postgresflex_database" "this" { + project_id = var.stackit_project_id + instance_id = stackit_postgresflex_instance.this.instance_id + name = "test" + owner = stackit_postgresflex_user.this.username +} diff --git a/examples/dbaas-otel-collect-metrics/04-service-account.tf b/examples/dbaas-otel-collect-metrics/04-service-account.tf new file mode 100644 index 0000000..eb25d4c --- /dev/null +++ b/examples/dbaas-otel-collect-metrics/04-service-account.tf @@ -0,0 +1,38 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +resource "stackit_service_account" "this" { + name = "prom-proxy" + project_id = var.stackit_project_id +} + +resource "time_rotating" "rotate" { + rotation_days = 150 +} + +resource "stackit_service_account_key" "this" { + project_id = var.stackit_project_id + service_account_email = stackit_service_account.this.email + ttl_days = 180 + + rotate_when_changed = { + rotation = time_rotating.rotate.id + } +} + +resource "stackit_authorization_project_role_assignment" "this" { + resource_id = var.stackit_project_id + role = "prometheus-proxy.reader" + subject = stackit_service_account.this.email +} diff --git a/examples/dbaas-otel-collect-metrics/05-otel-helm.tf b/examples/dbaas-otel-collect-metrics/05-otel-helm.tf new file mode 100644 index 0000000..acc8ee6 --- /dev/null +++ b/examples/dbaas-otel-collect-metrics/05-otel-helm.tf @@ -0,0 +1,65 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +locals { + sa_json = jsondecode(stackit_service_account_key.this.json) + otel_helm_values = templatefile("${path.module}/helm-values/otel-collector-values.tftpl", { + stackit_project_id = var.stackit_project_id + stackit_region = var.stackit_region + stackit_postgres_instance_id = stackit_postgresflex_instance.this.instance_id + observability_metrics_endpoint = stackit_observability_instance.example.metrics_push_url + secret_name = kubernetes_secret.otel_secret.metadata[0].name + sa_client_id = local.sa_json.credentials.sub + sa_issuer = local.sa_json.credentials.iss + sa_key_id = local.sa_json.credentials.kid + }) +} + + +resource "stackit_observability_credential" "otel" { + project_id = var.stackit_project_id + instance_id = stackit_observability_instance.example.instance_id +} + +resource "kubernetes_namespace" "monitoring" { + metadata { + name = "monitoring" + } +} + +resource "kubernetes_secret" "otel_secret" { + metadata { + name = "otel-secrets" + namespace = kubernetes_namespace.monitoring.metadata[0].name + } + + data = { + OBSERVABILITY_AUTHORIZATION_HEADER = "Basic ${base64encode("${stackit_observability_credential.otel.username}:${stackit_observability_credential.otel.password}")}" + JSON = stackit_service_account_key.this.json + PRIVATE_KEY = jsondecode(stackit_service_account_key.this.json).credentials.privateKey + } +} + +resource "helm_release" "opentelemetry_collector" { + name = "opentelemetry-collector" + repository = "https://open-telemetry.github.io/opentelemetry-helm-charts" + chart = "opentelemetry-collector" + version = "0.152.0" + namespace = kubernetes_namespace.monitoring.metadata[0].name + timeout = 30 + + values = [ + local.otel_helm_values + ] +} diff --git a/examples/dbaas-otel-collect-metrics/MAINTAINERS.md b/examples/dbaas-otel-collect-metrics/MAINTAINERS.md new file mode 100644 index 0000000..6457701 --- /dev/null +++ b/examples/dbaas-otel-collect-metrics/MAINTAINERS.md @@ -0,0 +1,9 @@ +# Maintainers + +General maintainers: + +- Mauritz Uphoff (Mauritz.Uphoff@digits.schwarz) + +This example is actively maintained. The owner is responsible for reviewing and updating dependencies and functionalities on a monthly basis. +For questions, issues, or feature requests, please email general maintainers. +Please include the BP name and version in your request. We will track your request as an issue. diff --git a/examples/dbaas-otel-collect-metrics/README.md b/examples/dbaas-otel-collect-metrics/README.md new file mode 100644 index 0000000..965b11b --- /dev/null +++ b/examples/dbaas-otel-collect-metrics/README.md @@ -0,0 +1,39 @@ +# DBaaS OpenTelemetry Metrics Collection + +Collect metrics from STACKIT PostgreSQL Flex and MongoDB instances using OpenTelemetry (OTel) and export them to STACKIT Observability. + +## Prerequisites + +- STACKIT Project ID and Service Account key. +- Terraform, `kubectl`, and `helm` installed. + +## Usage + +1. **Configure**: Update `stackit_project_id` and `stackit_service_account_key_path` in `01-variables.tf`. +2. **Deploy**: + ```bash + terraform init + terraform apply + ``` + +## Scrape Configuration + +The OTel Collector scrapes metrics from: + +- **PostgreSQL**: `https://postgres-prom-proxy.api.stackit.cloud/v2/...` +- **MongoDB**: `https://mongodb-prom-proxy.api.stackit.cloud/v2/...` + +_Note: MSSQL is not supported._ + +## Debugging + +View live scrape data in the collector logs: + +```bash +kubectl logs -l app.kubernetes.io/name=otel-collector -n monitoring -f +``` + +## Documentation + +- [PostgreSQL Flex Metrics](https://docs.stackit.cloud/products/databases/postgresql-flex/reference/observability-metrics-in-postgresql-flex/) +- [MongoDB Flex Metrics](https://docs.stackit.cloud/products/databases/mongodb-flex/reference/observability-metrics/) diff --git a/examples/dbaas-otel-collect-metrics/helm-values/otel-collector-values.tftpl b/examples/dbaas-otel-collect-metrics/helm-values/otel-collector-values.tftpl new file mode 100644 index 0000000..2f34dd0 --- /dev/null +++ b/examples/dbaas-otel-collect-metrics/helm-values/otel-collector-values.tftpl @@ -0,0 +1,79 @@ +fullnameOverride: otel-collector +mode: deployment + +podAnnotations: + stackit-sa-key-id: "${sa_key_id}" + +image: + repository: "otel/opentelemetry-collector-contrib" + +config: + receivers: + prometheus: + config: + scrape_configs: + - job_name: stackit-postgres + metrics_path: /v2/projects/$${STACKIT_PROJECT_ID}/regions/$${STACKIT_REGION}/instances/$${STACKIT_POSTGRES_INSTANCE_ID}/metrics + oauth2: + audience: $${SA_TOKEN_REQUEST_AUDIENCE} + client_certificate_key_file: /mnt/secrets-store/private-key + client_certificate_key_id: $${SA_TOKEN_REQUEST_CLIENT_CERTIFICATE_KEY_ID} + client_id: $${SA_TOKEN_REQUEST_CLIENT_ID} + grant_type: urn:ietf:params:oauth:grant-type:jwt-bearer + iss: $${SA_TOKEN_REQUEST_ISSUER} + signature_algorithm: RS512 + token_url: https://service-account.api.stackit.cloud/token + scheme: https + scrape_interval: 1m + static_configs: + - targets: + - postgres-prom-proxy.api.stackit.cloud:443 + exporters: + debug: + verbosity: normal + prometheusremotewrite: + endpoint: $${OBSERVABILITY_METRICS_ENDPOINT} + headers: + Authorization: $${OBSERVABILITY_AUTHORIZATION_HEADER} + + service: + pipelines: + metrics: + receivers: [prometheus] + exporters: [prometheusremotewrite, debug] + +extraEnvs: + - name: STACKIT_PROJECT_ID + value: "${stackit_project_id}" + - name: STACKIT_REGION + value: "${stackit_region}" + - name: STACKIT_POSTGRES_INSTANCE_ID + value: "${stackit_postgres_instance_id}" + - name: OBSERVABILITY_METRICS_ENDPOINT + value: "${observability_metrics_endpoint}" + - name: OBSERVABILITY_AUTHORIZATION_HEADER + valueFrom: + secretKeyRef: + name: ${secret_name} + key: OBSERVABILITY_AUTHORIZATION_HEADER + - name: SA_TOKEN_REQUEST_CLIENT_ID + value: "${sa_client_id}" + - name: SA_TOKEN_REQUEST_ISSUER + value: "${sa_issuer}" + - name: SA_TOKEN_REQUEST_CLIENT_CERTIFICATE_KEY_ID + value: "${sa_key_id}" + - name: SA_TOKEN_REQUEST_AUDIENCE + value: "https://service-account.api.stackit.cloud/token" + +extraVolumes: + - name: otel-secrets + secret: + secretName: ${secret_name} + items: + - key: PRIVATE_KEY + path: private-key + +extraVolumeMounts: + - name: otel-secrets + mountPath: /mnt/secrets-store + readOnly: true diff --git a/examples/iaas-cross-az-layer4-loadbalancer/.terraform.lock.hcl b/examples/iaas-cross-az-layer4-loadbalancer/.terraform.lock.hcl index bd80b22..eeb1632 100644 --- a/examples/iaas-cross-az-layer4-loadbalancer/.terraform.lock.hcl +++ b/examples/iaas-cross-az-layer4-loadbalancer/.terraform.lock.hcl @@ -5,6 +5,7 @@ provider "registry.terraform.io/hashicorp/random" { version = "3.8.1" constraints = ">= 3.6.3" hashes = [ + "h1:Eexl06+6J+s75uD46+WnZtpJZYRVUMB0AiuPBifK6Jc=", "h1:u8AKlWVDTH5r9YLSeswoVEjiY72Rt4/ch7U+61ZDkiQ=", "zh:08dd03b918c7b55713026037c5400c48af5b9f468f483463321bd18e17b907b4", "zh:0eee654a5542dc1d41920bbf2419032d6f0d5625b03bd81339e5b33394a3e0ae", @@ -26,6 +27,7 @@ provider "registry.terraform.io/stackitcloud/stackit" { constraints = ">= 0.87.0" hashes = [ "h1:8de9n+Roq6Z2Ltp9poBBBN9a4zSpx73VLpgFS5mTyoI=", + "h1:RStdHSDwbtonYfg7mR5Y92v6fxIVX9FEz0UN+tm9kHI=", "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", "zh:0ed12db90276ccd2d6f87135b7dd078657823c3ca33121c6a157d0bdf08f801e", "zh:160b32bcf1d01666784cf8469e10e0a38d4c3d24c80c0c5be470cc63ef27ea62", diff --git a/examples/iaas-cross-az-layer7-loadbalancer-waf/.terraform.lock.hcl b/examples/iaas-cross-az-layer7-loadbalancer-waf/.terraform.lock.hcl index 5e195e5..25ece83 100644 --- a/examples/iaas-cross-az-layer7-loadbalancer-waf/.terraform.lock.hcl +++ b/examples/iaas-cross-az-layer7-loadbalancer-waf/.terraform.lock.hcl @@ -5,6 +5,7 @@ provider "registry.terraform.io/hashicorp/random" { version = "3.8.1" constraints = ">= 3.6.3" hashes = [ + "h1:Eexl06+6J+s75uD46+WnZtpJZYRVUMB0AiuPBifK6Jc=", "h1:u8AKlWVDTH5r9YLSeswoVEjiY72Rt4/ch7U+61ZDkiQ=", "zh:08dd03b918c7b55713026037c5400c48af5b9f468f483463321bd18e17b907b4", "zh:0eee654a5542dc1d41920bbf2419032d6f0d5625b03bd81339e5b33394a3e0ae", @@ -24,6 +25,7 @@ provider "registry.terraform.io/hashicorp/random" { provider "registry.terraform.io/hashicorp/tls" { version = "4.2.1" hashes = [ + "h1:F5d6bQY8UlBo0D71Sv7CsV+3aZOFz0yeNF+vufog7h4=", "h1:akFNuHwvrtnYMBofieoeXhPJDhYZzJVu/Q/BgZK2fgg=", "zh:0d1e7d07ac973b97fa228f46596c800de830820506ee145626f079dd6bbf8d8a", "zh:5c7e3d4348cb4861ab812973ef493814a4b224bdd3e9d534a7c8a7c992382b86", @@ -42,8 +44,9 @@ provider "registry.terraform.io/hashicorp/tls" { provider "registry.terraform.io/mastercard/restapi" { version = "3.0.0" - constraints = "3.0.0" + constraints = ">= 3.0.0" hashes = [ + "h1:Fqxoc6bsydl6iWGx6ZvyqUDdGt7Cb4sW/BSHhBeHGgw=", "h1:y1I3azDHOqRySTyDHsb3Xh1waP/99KfykZRagbRx1qI=", "zh:0b63bd3c25a31f090a41933f90b7dd6e984add1c4261d8f5caa73f4d5aa065a4", "zh:1c3e89cf19118fc07d7b04257251fc9897e722c16e0a0df7b07fcd261f8c12e7", @@ -68,6 +71,7 @@ provider "registry.terraform.io/stackitcloud/stackit" { constraints = ">= 0.87.0" hashes = [ "h1:8de9n+Roq6Z2Ltp9poBBBN9a4zSpx73VLpgFS5mTyoI=", + "h1:RStdHSDwbtonYfg7mR5Y92v6fxIVX9FEz0UN+tm9kHI=", "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", "zh:0ed12db90276ccd2d6f87135b7dd078657823c3ca33121c6a157d0bdf08f801e", "zh:160b32bcf1d01666784cf8469e10e0a38d4c3d24c80c0c5be470cc63ef27ea62", diff --git a/examples/iaas-ha-vrrp/.terraform.lock.hcl b/examples/iaas-ha-vrrp/.terraform.lock.hcl index 22969f3..c8e7f0a 100644 --- a/examples/iaas-ha-vrrp/.terraform.lock.hcl +++ b/examples/iaas-ha-vrrp/.terraform.lock.hcl @@ -5,6 +5,7 @@ provider "registry.terraform.io/hashicorp/random" { version = "3.8.1" constraints = ">= 3.6.3" hashes = [ + "h1:Eexl06+6J+s75uD46+WnZtpJZYRVUMB0AiuPBifK6Jc=", "h1:u8AKlWVDTH5r9YLSeswoVEjiY72Rt4/ch7U+61ZDkiQ=", "zh:08dd03b918c7b55713026037c5400c48af5b9f468f483463321bd18e17b907b4", "zh:0eee654a5542dc1d41920bbf2419032d6f0d5625b03bd81339e5b33394a3e0ae", @@ -25,6 +26,7 @@ provider "registry.terraform.io/stackitcloud/stackit" { version = "0.90.0" constraints = ">= 0.87.0" hashes = [ + "h1:QgP6TOtucJ3A6fA51rdUvxhYGjl9RrWvXQZpjHTOuiU=", "h1:W29Kv6XUxYssF2Gy8KcmTx3EFstt6k8sKgPRIBbq+qs=", "zh:003af58a84884558bbb2fc40fcbefa6774ec20aa9e4b97cf3f950190a600afd2", "zh:026ee9cef4670cf33369f8654c6b9b1d8c0e116ceb0b353c882be222951ecdd4", diff --git a/examples/iaas-volume-encryption/.terraform.lock.hcl b/examples/iaas-volume-encryption/.terraform.lock.hcl index 7c3993a..f4f00c9 100644 --- a/examples/iaas-volume-encryption/.terraform.lock.hcl +++ b/examples/iaas-volume-encryption/.terraform.lock.hcl @@ -5,6 +5,7 @@ provider "registry.terraform.io/stackitcloud/stackit" { version = "0.80.0" constraints = "0.80.0" hashes = [ + "h1:VqmLlSV9sMOX7aq5Bnsj18KNKCUPFahZzf0SA5fTkVk=", "h1:wz7uGwzVoo1NO18CDLcfjLraTSiWQ5EzJnDeCKcFi60=", "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", "zh:3a0e6cb125ef76a24b2b5ff9c786c57058f385571d283bd68f633225fcca695a", diff --git a/examples/pfsense-hub-and-spoke/cloud-init/user-init-linux.yml b/examples/pfsense-hub-and-spoke/cloud-init/user-init-linux.yml index 6850de0..be6e579 100644 --- a/examples/pfsense-hub-and-spoke/cloud-init/user-init-linux.yml +++ b/examples/pfsense-hub-and-spoke/cloud-init/user-init-linux.yml @@ -8,7 +8,7 @@ # default password in production. # # Generate a SHA-512 hash on Linux/macOS: -# python3 -c "import crypt; print(crypt.crypt('YourPassword', crypt.mksalt(crypt.METHOD_SHA512)))" +# openssl passwd -6 "YourPassword" # --------------------------------------------------------------------------- users: - name: admin-user diff --git a/examples/resourcemanager-nested-folders/.terraform.lock.hcl b/examples/resourcemanager-nested-folders/.terraform.lock.hcl index c9888a0..0fdab96 100644 --- a/examples/resourcemanager-nested-folders/.terraform.lock.hcl +++ b/examples/resourcemanager-nested-folders/.terraform.lock.hcl @@ -5,6 +5,7 @@ provider "registry.terraform.io/hashicorp/random" { version = "3.6.3" constraints = "3.6.3" hashes = [ + "h1:Fnaec9vA8sZ8BXVlN3Xn9Jz3zghSETIKg7ch8oXhxno=", "h1:zG9uFP8l9u+yGZZvi5Te7PV62j50azpgwPunq2vTm1E=", "zh:04ceb65210251339f07cd4611885d242cd4d0c7306e86dda9785396807c00451", "zh:448f56199f3e99ff75d5c0afacae867ee795e4dfda6cb5f8e3b2a72ec3583dd8", @@ -25,6 +26,7 @@ provider "registry.terraform.io/stackitcloud/stackit" { version = "0.90.0" constraints = ">= 0.66.0" hashes = [ + "h1:QgP6TOtucJ3A6fA51rdUvxhYGjl9RrWvXQZpjHTOuiU=", "h1:W29Kv6XUxYssF2Gy8KcmTx3EFstt6k8sKgPRIBbq+qs=", "zh:003af58a84884558bbb2fc40fcbefa6774ec20aa9e4b97cf3f950190a600afd2", "zh:026ee9cef4670cf33369f8654c6b9b1d8c0e116ceb0b353c882be222951ecdd4", diff --git a/examples/resourcemanager-nested-folders/README.md b/examples/resourcemanager-nested-folders/README.md index 1e99e45..b3d356d 100644 --- a/examples/resourcemanager-nested-folders/README.md +++ b/examples/resourcemanager-nested-folders/README.md @@ -2,4 +2,6 @@ ## Overview +> ⚠️ Two levels of folders must be enabled via a support ticket. By default, only one level is possible. + This repository demonstrates code to generate nested folders within a project. diff --git a/examples/s3-aws-terraform-provider/.terraform.lock.hcl b/examples/s3-aws-terraform-provider/.terraform.lock.hcl new file mode 100644 index 0000000..8873576 --- /dev/null +++ b/examples/s3-aws-terraform-provider/.terraform.lock.hcl @@ -0,0 +1,47 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "5.100.0" + constraints = "~> 5.0" + hashes = [ + "h1:edXOJWE4ORX8Fm+dpVpICzMZJat4AX0VRCAy/xkcOc0=", + "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", + "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", + "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", + "zh:6330766f1d85f01ae6ea90d1b214b8b74cc8c1badc4696b165b36ddd4cc15f7b", + "zh:7c8c2e30d8e55291b86fcb64bdf6c25489d538688545eb48fd74ad622e5d3862", + "zh:99b1003bd9bd32ee323544da897148f46a527f622dc3971af63ea3e251596342", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9f8b909d3ec50ade83c8062290378b1ec553edef6a447c56dadc01a99f4eaa93", + "zh:aaef921ff9aabaf8b1869a86d692ebd24fbd4e12c21205034bb679b9caf883a2", + "zh:ac882313207aba00dd5a76dbd572a0ddc818bb9cbf5c9d61b28fe30efaec951e", + "zh:bb64e8aff37becab373a1a0cc1080990785304141af42ed6aa3dd4913b000421", + "zh:dfe495f6621df5540d9c92ad40b8067376350b005c637ea6efac5dc15028add4", + "zh:f0ddf0eaf052766cfe09dea8200a946519f653c384ab4336e2a4a64fdd6310e9", + "zh:f1b7e684f4c7ae1eed272b6de7d2049bb87a0275cb04dbb7cda6636f600699c9", + "zh:ff461571e3f233699bf690db319dfe46aec75e58726636a0d97dd9ac6e32fb70", + ] +} + +provider "registry.terraform.io/stackitcloud/stackit" { + version = "0.94.0" + constraints = "> 0.90.0" + hashes = [ + "h1:ikFzd4yeJ1LR8ojP2PsZwiK2ZLhxBjRXkEg2HJrI07U=", + "zh:06c8da7d8a048216e825fa7d1e45949c1bda2a5f53f9bb0556b83b6610703fe6", + "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", + "zh:19e82636cfd52a65105e0cf030bc8a0c815082818ef953b84f9b1e349a87318c", + "zh:24af9b7d2f1bb38f480b1aa8cf5e4ecf483bd4403642a9e8a5accbe1ae212feb", + "zh:3b10850e9242bcd00c519ff4140130e8443002fd60b6dff90983e7cb1973b2c3", + "zh:54837a0fa4ddbcf0b8407718f8823b831322deba3bd7ec8492e4578928f50633", + "zh:5cfd6a6b1ca73826a03f8746ef84a5c4059648bc49abf8056c8e0f9b87800a23", + "zh:6ab3bcfef6ff65b4ce76d333b4ad99e5f91991fcf5bddbe1958aadde6ee05eab", + "zh:81b96dc29b055f15e475d8bc32482617a582785949b3c02f44ef15d19951f69c", + "zh:85f478c2fcf10219263462d0f06b5cc41603b1edad813c336e100b3e0a55bfe8", + "zh:9adbb7655fddfe4d4081746d0d7e39c3e8fbf8aa3d8b7d3b5164f30c16a6bd93", + "zh:9c24b39e788283ead8a8ce1f013a47562ff0dc1ccb642a8e18644cbdcda0f1c4", + "zh:a425f28d6a5f6f024cab56c848c55025e84a09db946f1b00a2655d9567251cea", + "zh:f28aa62d2f06e08fe6d18ef9103a8164aa9278540779bebd61120f810c603c6b", + ] +} diff --git a/examples/secretsmanager-vault-terraform-provider/.terraform.lock.hcl b/examples/secretsmanager-vault-terraform-provider/.terraform.lock.hcl new file mode 100644 index 0000000..474bc20 --- /dev/null +++ b/examples/secretsmanager-vault-terraform-provider/.terraform.lock.hcl @@ -0,0 +1,44 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/vault" { + version = "5.9.0" + constraints = "5.9.0" + hashes = [ + "h1:8wcXxEMo7XvCnrtZHSpAuWmRfYiZkWn2tssshB1BDzo=", + "zh:16e23a37c0965938544af282a7bc13dabca445f462ab27829f98e936ace4d263", + "zh:249fcf9da1a690fe9aa44a7421fad89a425afb0c2ce7eaf306d75daddd691af5", + "zh:3d92af386049a229a428f21b938a22df61703447c8ceed65c73f111a64e627d2", + "zh:4033fedf9d4f54f0aacf7c4a79e20978bcd67c0a8ab9411acd447db1469108a4", + "zh:51c78d0dc378037bbaf3cd26ff29fae7c40d7b134b40d059b982257987c15f9f", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:86e414b7327343de676ec506d30c557a514dbd992b27a2670466adaf9ed69718", + "zh:879c3a61ed8d183a68ddb590e63a7e0d6aab8d8044fd4a13658e7b1661395a9d", + "zh:8d548617543ee2ce0340972a5df93e7ac37b7895d4bf506bd587f8daac58e6d6", + "zh:8d75b3bbfd9a536c8c1d84504cb3d1c8e1a3fd30e377a51a6311476632363103", + "zh:922f625a36642c49daa432e07c12e72ff75025e0b9afda8d7240f38c6789fe46", + "zh:fbceae685b395acaff6c820ed7d7eaa6250ef4769e04481145dc50e09b89db2f", + ] +} + +provider "registry.terraform.io/stackitcloud/stackit" { + version = "0.94.0" + constraints = ">= 0.94.0" + hashes = [ + "h1:ikFzd4yeJ1LR8ojP2PsZwiK2ZLhxBjRXkEg2HJrI07U=", + "zh:06c8da7d8a048216e825fa7d1e45949c1bda2a5f53f9bb0556b83b6610703fe6", + "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", + "zh:19e82636cfd52a65105e0cf030bc8a0c815082818ef953b84f9b1e349a87318c", + "zh:24af9b7d2f1bb38f480b1aa8cf5e4ecf483bd4403642a9e8a5accbe1ae212feb", + "zh:3b10850e9242bcd00c519ff4140130e8443002fd60b6dff90983e7cb1973b2c3", + "zh:54837a0fa4ddbcf0b8407718f8823b831322deba3bd7ec8492e4578928f50633", + "zh:5cfd6a6b1ca73826a03f8746ef84a5c4059648bc49abf8056c8e0f9b87800a23", + "zh:6ab3bcfef6ff65b4ce76d333b4ad99e5f91991fcf5bddbe1958aadde6ee05eab", + "zh:81b96dc29b055f15e475d8bc32482617a582785949b3c02f44ef15d19951f69c", + "zh:85f478c2fcf10219263462d0f06b5cc41603b1edad813c336e100b3e0a55bfe8", + "zh:9adbb7655fddfe4d4081746d0d7e39c3e8fbf8aa3d8b7d3b5164f30c16a6bd93", + "zh:9c24b39e788283ead8a8ce1f013a47562ff0dc1ccb642a8e18644cbdcda0f1c4", + "zh:a425f28d6a5f6f024cab56c848c55025e84a09db946f1b00a2655d9567251cea", + "zh:f28aa62d2f06e08fe6d18ef9103a8164aa9278540779bebd61120f810c603c6b", + ] +} diff --git a/examples/secretsmanager-vault-terraform-provider/main.tf b/examples/secretsmanager-vault-terraform-provider/main.tf index ddd4b6e..bea426c 100644 --- a/examples/secretsmanager-vault-terraform-provider/main.tf +++ b/examples/secretsmanager-vault-terraform-provider/main.tf @@ -12,11 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -provider "stackit" { - default_region = "eu01" - service_account_key_path = "" -} - resource "stackit_secretsmanager_instance" "example" { project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" name = "example-instance" @@ -29,16 +24,6 @@ resource "stackit_secretsmanager_user" "example" { write_enabled = true } -provider "vault" { - address = "https://prod.sm.eu01.stackit.cloud" - skip_child_token = true - - auth_login_userpass { - username = stackit_secretsmanager_user.example.username - password = stackit_secretsmanager_user.example.password - } -} - resource "stackit_observability_instance" "example" { project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" name = "example-instance" diff --git a/examples/secretsmanager-vault-terraform-provider/provider.tf b/examples/secretsmanager-vault-terraform-provider/provider.tf new file mode 100644 index 0000000..cf73ad6 --- /dev/null +++ b/examples/secretsmanager-vault-terraform-provider/provider.tf @@ -0,0 +1,41 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_providers { + stackit = { + source = "stackitcloud/stackit" + version = ">= 0.94.0" + } + vault = { + source = "hashicorp/vault" + version = "5.9.0" + } + } +} + +provider "stackit" { + default_region = "eu01" + service_account_key_path = "" +} + +provider "vault" { + address = "https://prod.sm.eu01.stackit.cloud" + skip_child_token = true + + auth_login_userpass { + username = stackit_secretsmanager_user.example.username + password = stackit_secretsmanager_user.example.password + } +} diff --git a/examples/ske-encrypted-volumes/.terraform.lock.hcl b/examples/ske-encrypted-volumes/.terraform.lock.hcl new file mode 100644 index 0000000..39718fe --- /dev/null +++ b/examples/ske-encrypted-volumes/.terraform.lock.hcl @@ -0,0 +1,44 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "3.1.0" + constraints = ">= 3.1.0" + hashes = [ + "h1:oodIAuFMikXNmEtil5MQgP4dfSctUBYQiGJfjbsF3NY=", + "zh:0215c5c60be62028c09a2f22458e89cda3ef5830a632299f1d401eb3538874b0", + "zh:09ebb9f442431e278a310a9423f32caf467cb4b3cad3fe59573ca71fa7b14e20", + "zh:0c4e5912f83bb35846ae0a9ae54fc320706ee61894cd21cc6b4181b1c5a2fa5c", + "zh:1678c982853ad461e65ccb5e79d585e13ed109dd47dab2a66d3a7a304faeef65", + "zh:1c050a5c15e330457a9c18caacf61a923c59d663e13f2962e4b32f04fef523a0", + "zh:2c55bcec83be58ec132c7cb0a1ac644758b800d794fdc636d53a0eada0358a3a", + "zh:a062bb0aa316c08d8460c66a5d68da71da40de5d3bc3b31abcf3a1a9a19650f1", + "zh:a26fdea0afaa9b247c73c0b42843ca51ba7db0ac2571f9d3d50dcabd20ca1b98", + "zh:c872c9385a78d502bf5823d61cd3bb0f9a0585030e025eb12585c83451beeaa1", + "zh:f180879af931182beee4c8c0d9dab62b81d86f17ddcbe3786ef4c7cec9163a4e", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f70f5789264069e0eef06f9b5d5fde955ef7206f7d446d1ce51a4c37a3f3e02f", + ] +} + +provider "registry.terraform.io/stackitcloud/stackit" { + version = "0.94.0" + constraints = ">= 0.94.0" + hashes = [ + "h1:ikFzd4yeJ1LR8ojP2PsZwiK2ZLhxBjRXkEg2HJrI07U=", + "zh:06c8da7d8a048216e825fa7d1e45949c1bda2a5f53f9bb0556b83b6610703fe6", + "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", + "zh:19e82636cfd52a65105e0cf030bc8a0c815082818ef953b84f9b1e349a87318c", + "zh:24af9b7d2f1bb38f480b1aa8cf5e4ecf483bd4403642a9e8a5accbe1ae212feb", + "zh:3b10850e9242bcd00c519ff4140130e8443002fd60b6dff90983e7cb1973b2c3", + "zh:54837a0fa4ddbcf0b8407718f8823b831322deba3bd7ec8492e4578928f50633", + "zh:5cfd6a6b1ca73826a03f8746ef84a5c4059648bc49abf8056c8e0f9b87800a23", + "zh:6ab3bcfef6ff65b4ce76d333b4ad99e5f91991fcf5bddbe1958aadde6ee05eab", + "zh:81b96dc29b055f15e475d8bc32482617a582785949b3c02f44ef15d19951f69c", + "zh:85f478c2fcf10219263462d0f06b5cc41603b1edad813c336e100b3e0a55bfe8", + "zh:9adbb7655fddfe4d4081746d0d7e39c3e8fbf8aa3d8b7d3b5164f30c16a6bd93", + "zh:9c24b39e788283ead8a8ce1f013a47562ff0dc1ccb642a8e18644cbdcda0f1c4", + "zh:a425f28d6a5f6f024cab56c848c55025e84a09db946f1b00a2655d9567251cea", + "zh:f28aa62d2f06e08fe6d18ef9103a8164aa9278540779bebd61120f810c603c6b", + ] +} diff --git a/examples/ske-encrypted-volumes/main.tf b/examples/ske-encrypted-volumes/main.tf index 8e2d010..55d2826 100644 --- a/examples/ske-encrypted-volumes/main.tf +++ b/examples/ske-encrypted-volumes/main.tf @@ -12,18 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -provider "stackit" { - default_region = "eu01" - service_account_key_path = "" -} - -provider "kubernetes" { - host = yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.server - client_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-certificate-data) - client_key = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-key-data) - cluster_ca_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.certificate-authority-data) -} - resource "stackit_ske_cluster" "default" { project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" name = "ske-enc-vol" diff --git a/examples/ske-encrypted-volumes/provider.tf b/examples/ske-encrypted-volumes/provider.tf new file mode 100644 index 0000000..7c46d2b --- /dev/null +++ b/examples/ske-encrypted-volumes/provider.tf @@ -0,0 +1,38 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_providers { + stackit = { + source = "stackitcloud/stackit" + version = ">= 0.94.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 3.1.0" + } + } +} + +provider "stackit" { + default_region = "eu01" + service_account_key_path = "" +} + +provider "kubernetes" { + host = yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.server + client_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-certificate-data) + client_key = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-key-data) + cluster_ca_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.certificate-authority-data) +} diff --git a/examples/ske-external-secrets-sync/.terraform.lock.hcl b/examples/ske-external-secrets-sync/.terraform.lock.hcl index fbb7035..f7f082b 100644 --- a/examples/ske-external-secrets-sync/.terraform.lock.hcl +++ b/examples/ske-external-secrets-sync/.terraform.lock.hcl @@ -5,6 +5,7 @@ provider "registry.terraform.io/hashicorp/helm" { version = "2.17.0" constraints = "2.17.0" hashes = [ + "h1:K5FEjxvDnxb1JF1kG1xr8J3pNGxoaR3Z0IBG9Csm/Is=", "h1:kQMkcPVvHOguOqnxoEU2sm1ND9vCHiT8TvZ2x6v/Rsw=", "zh:06fb4e9932f0afc1904d2279e6e99353c2ddac0d765305ce90519af410706bd4", "zh:104eccfc781fc868da3c7fec4385ad14ed183eb985c96331a1a937ac79c2d1a7", @@ -26,6 +27,7 @@ provider "registry.terraform.io/hashicorp/kubernetes" { constraints = ">= 2.25.2" hashes = [ "h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=", + "h1:vyHdH0p6bf9xp1NPePObAJkXTJb/I09FQQmmevTzZe0=", "zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281", "zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba", "zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7", @@ -45,6 +47,7 @@ provider "registry.terraform.io/hashicorp/random" { version = "3.7.2" constraints = "3.7.2" hashes = [ + "h1:356j/3XnXEKr9nyicLUufzoF4Yr6hRy481KIxRVpK0c=", "h1:KG4NuIBl1mRWU0KD/BGfCi1YN/j3F7H4YgeeM7iSdNs=", "zh:14829603a32e4bc4d05062f059e545a91e27ff033756b48afbae6b3c835f508f", "zh:1527fb07d9fea400d70e9e6eb4a2b918d5060d604749b6f1c361518e7da546dc", @@ -64,6 +67,7 @@ provider "registry.terraform.io/hashicorp/random" { provider "registry.terraform.io/hashicorp/vault" { version = "5.8.0" hashes = [ + "h1:eSJgYoJoVMce2xjJJCeAZnJELsC4RoqaotD0fgfn6dw=", "h1:gk1cR+x1D+TEz05MKWmpp0p06+Trob5cN0eYU1vZGJs=", "zh:18e79b42c8c155a5c541a45d54a6ccdeab23c404c239acdeed336a17cbfc2fd4", "zh:241f50d1ea40030578034b4440e41676f1c9b5e8a2be5cd3afdb6e387914e0bf", @@ -84,6 +88,7 @@ provider "registry.terraform.io/stackitcloud/stackit" { version = "0.90.0" constraints = ">= 0.66.0" hashes = [ + "h1:QgP6TOtucJ3A6fA51rdUvxhYGjl9RrWvXQZpjHTOuiU=", "h1:W29Kv6XUxYssF2Gy8KcmTx3EFstt6k8sKgPRIBbq+qs=", "zh:003af58a84884558bbb2fc40fcbefa6774ec20aa9e4b97cf3f950190a600afd2", "zh:026ee9cef4670cf33369f8654c6b9b1d8c0e116ceb0b353c882be222951ecdd4", diff --git a/examples/ske-gpu-operator/.terraform.lock.hcl b/examples/ske-gpu-operator/.terraform.lock.hcl index 2cebd8e..9772a39 100644 --- a/examples/ske-gpu-operator/.terraform.lock.hcl +++ b/examples/ske-gpu-operator/.terraform.lock.hcl @@ -5,6 +5,7 @@ provider "registry.terraform.io/hashicorp/helm" { version = "3.1.1" hashes = [ "h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=", + "h1:5b2ojWKT0noujHiweCds37ZreRFRQLNaErdJLusJN88=", "zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275", "zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a", "zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29", @@ -25,6 +26,7 @@ provider "registry.terraform.io/hashicorp/kubernetes" { constraints = ">= 2.14.0" hashes = [ "h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=", + "h1:vyHdH0p6bf9xp1NPePObAJkXTJb/I09FQQmmevTzZe0=", "zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281", "zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba", "zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7", @@ -42,9 +44,10 @@ provider "registry.terraform.io/hashicorp/kubernetes" { provider "registry.terraform.io/stackitcloud/stackit" { version = "0.91.0" - constraints = "> 0.60.0" + constraints = ">= 0.60.0" hashes = [ "h1:8de9n+Roq6Z2Ltp9poBBBN9a4zSpx73VLpgFS5mTyoI=", + "h1:RStdHSDwbtonYfg7mR5Y92v6fxIVX9FEz0UN+tm9kHI=", "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", "zh:0ed12db90276ccd2d6f87135b7dd078657823c3ca33121c6a157d0bdf08f801e", "zh:160b32bcf1d01666784cf8469e10e0a38d4c3d24c80c0c5be470cc63ef27ea62", diff --git a/examples/ske-kubernetes-terraform-provider/.terraform.lock.hcl b/examples/ske-kubernetes-terraform-provider/.terraform.lock.hcl new file mode 100644 index 0000000..de5a520 --- /dev/null +++ b/examples/ske-kubernetes-terraform-provider/.terraform.lock.hcl @@ -0,0 +1,44 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.38.0" + constraints = "~> 2.24" + hashes = [ + "h1:5CkveFo5ynsLdzKk+Kv+r7+U9rMrNjfZPT3a0N/fhgE=", + "zh:0af928d776eb269b192dc0ea0f8a3f0f5ec117224cd644bdacdc682300f84ba0", + "zh:1be998e67206f7cfc4ffe77c01a09ac91ce725de0abaec9030b22c0a832af44f", + "zh:326803fe5946023687d603f6f1bab24de7af3d426b01d20e51d4e6fbe4e7ec1b", + "zh:4a99ec8d91193af961de1abb1f824be73df07489301d62e6141a656b3ebfff12", + "zh:5136e51765d6a0b9e4dbcc3b38821e9736bd2136cf15e9aac11668f22db117d2", + "zh:63fab47349852d7802fb032e4f2b6a101ee1ce34b62557a9ad0f0f0f5b6ecfdc", + "zh:924fb0257e2d03e03e2bfe9c7b99aa73c195b1f19412ca09960001bee3c50d15", + "zh:b63a0be5e233f8f6727c56bed3b61eb9456ca7a8bb29539fba0837f1badf1396", + "zh:d39861aa21077f1bc899bc53e7233262e530ba8a3a2d737449b100daeb303e4d", + "zh:de0805e10ebe4c83ce3b728a67f6b0f9d18be32b25146aa89116634df5145ad4", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:faf23e45f0090eef8ba28a8aac7ec5d4fdf11a36c40a8d286304567d71c1e7db", + ] +} + +provider "registry.terraform.io/stackitcloud/stackit" { + version = "0.94.0" + constraints = "~> 0.35" + hashes = [ + "h1:ikFzd4yeJ1LR8ojP2PsZwiK2ZLhxBjRXkEg2HJrI07U=", + "zh:06c8da7d8a048216e825fa7d1e45949c1bda2a5f53f9bb0556b83b6610703fe6", + "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", + "zh:19e82636cfd52a65105e0cf030bc8a0c815082818ef953b84f9b1e349a87318c", + "zh:24af9b7d2f1bb38f480b1aa8cf5e4ecf483bd4403642a9e8a5accbe1ae212feb", + "zh:3b10850e9242bcd00c519ff4140130e8443002fd60b6dff90983e7cb1973b2c3", + "zh:54837a0fa4ddbcf0b8407718f8823b831322deba3bd7ec8492e4578928f50633", + "zh:5cfd6a6b1ca73826a03f8746ef84a5c4059648bc49abf8056c8e0f9b87800a23", + "zh:6ab3bcfef6ff65b4ce76d333b4ad99e5f91991fcf5bddbe1958aadde6ee05eab", + "zh:81b96dc29b055f15e475d8bc32482617a582785949b3c02f44ef15d19951f69c", + "zh:85f478c2fcf10219263462d0f06b5cc41603b1edad813c336e100b3e0a55bfe8", + "zh:9adbb7655fddfe4d4081746d0d7e39c3e8fbf8aa3d8b7d3b5164f30c16a6bd93", + "zh:9c24b39e788283ead8a8ce1f013a47562ff0dc1ccb642a8e18644cbdcda0f1c4", + "zh:a425f28d6a5f6f024cab56c848c55025e84a09db946f1b00a2655d9567251cea", + "zh:f28aa62d2f06e08fe6d18ef9103a8164aa9278540779bebd61120f810c603c6b", + ] +} diff --git a/examples/ske-nginx-rate-limit/.terraform.lock.hcl b/examples/ske-nginx-rate-limit/.terraform.lock.hcl index 1adc572..1c27261 100644 --- a/examples/ske-nginx-rate-limit/.terraform.lock.hcl +++ b/examples/ske-nginx-rate-limit/.terraform.lock.hcl @@ -5,6 +5,7 @@ provider "registry.terraform.io/hashicorp/helm" { version = "3.1.1" hashes = [ "h1:47CqNwkxctJtL/N/JuEj+8QMg8mRNI/NWeKO5/ydfZU=", + "h1:5b2ojWKT0noujHiweCds37ZreRFRQLNaErdJLusJN88=", "zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275", "zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a", "zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29", @@ -25,6 +26,7 @@ provider "registry.terraform.io/hashicorp/kubernetes" { constraints = ">= 2.14.0" hashes = [ "h1:P0c8knzZnouTNFIRij8IS7+pqd0OKaFDYX0j4GRsiqo=", + "h1:vyHdH0p6bf9xp1NPePObAJkXTJb/I09FQQmmevTzZe0=", "zh:02d55b0b2238fd17ffa12d5464593864e80f402b90b31f6e1bd02249b9727281", "zh:20b93a51bfeed82682b3c12f09bac3031f5bdb4977c47c97a042e4df4fb2f9ba", "zh:6e14486ecfaee38c09ccf33d4fdaf791409f90795c1b66e026c226fad8bc03c7", @@ -43,6 +45,7 @@ provider "registry.terraform.io/hashicorp/kubernetes" { provider "registry.terraform.io/hashicorp/random" { version = "3.8.1" hashes = [ + "h1:Eexl06+6J+s75uD46+WnZtpJZYRVUMB0AiuPBifK6Jc=", "h1:u8AKlWVDTH5r9YLSeswoVEjiY72Rt4/ch7U+61ZDkiQ=", "zh:08dd03b918c7b55713026037c5400c48af5b9f468f483463321bd18e17b907b4", "zh:0eee654a5542dc1d41920bbf2419032d6f0d5625b03bd81339e5b33394a3e0ae", @@ -63,6 +66,7 @@ provider "registry.terraform.io/stackitcloud/stackit" { version = "0.90.0" constraints = ">= 0.66.0" hashes = [ + "h1:QgP6TOtucJ3A6fA51rdUvxhYGjl9RrWvXQZpjHTOuiU=", "h1:W29Kv6XUxYssF2Gy8KcmTx3EFstt6k8sKgPRIBbq+qs=", "zh:003af58a84884558bbb2fc40fcbefa6774ec20aa9e4b97cf3f950190a600afd2", "zh:026ee9cef4670cf33369f8654c6b9b1d8c0e116ceb0b353c882be222951ecdd4", diff --git a/examples/ske-observability-alerting-kube-state-metrics/.terraform.lock.hcl b/examples/ske-observability-alerting-kube-state-metrics/.terraform.lock.hcl new file mode 100644 index 0000000..3e3b5bf --- /dev/null +++ b/examples/ske-observability-alerting-kube-state-metrics/.terraform.lock.hcl @@ -0,0 +1,64 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/helm" { + version = "3.1.1" + constraints = ">= 3.1.1" + hashes = [ + "h1:5b2ojWKT0noujHiweCds37ZreRFRQLNaErdJLusJN88=", + "zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275", + "zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a", + "zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29", + "zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104", + "zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990", + "zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34", + "zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8", + "zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1", + "zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b", + "zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903", + "zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "3.1.0" + constraints = ">= 3.1.0" + hashes = [ + "h1:oodIAuFMikXNmEtil5MQgP4dfSctUBYQiGJfjbsF3NY=", + "zh:0215c5c60be62028c09a2f22458e89cda3ef5830a632299f1d401eb3538874b0", + "zh:09ebb9f442431e278a310a9423f32caf467cb4b3cad3fe59573ca71fa7b14e20", + "zh:0c4e5912f83bb35846ae0a9ae54fc320706ee61894cd21cc6b4181b1c5a2fa5c", + "zh:1678c982853ad461e65ccb5e79d585e13ed109dd47dab2a66d3a7a304faeef65", + "zh:1c050a5c15e330457a9c18caacf61a923c59d663e13f2962e4b32f04fef523a0", + "zh:2c55bcec83be58ec132c7cb0a1ac644758b800d794fdc636d53a0eada0358a3a", + "zh:a062bb0aa316c08d8460c66a5d68da71da40de5d3bc3b31abcf3a1a9a19650f1", + "zh:a26fdea0afaa9b247c73c0b42843ca51ba7db0ac2571f9d3d50dcabd20ca1b98", + "zh:c872c9385a78d502bf5823d61cd3bb0f9a0585030e025eb12585c83451beeaa1", + "zh:f180879af931182beee4c8c0d9dab62b81d86f17ddcbe3786ef4c7cec9163a4e", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f70f5789264069e0eef06f9b5d5fde955ef7206f7d446d1ce51a4c37a3f3e02f", + ] +} + +provider "registry.terraform.io/stackitcloud/stackit" { + version = "0.94.0" + constraints = ">= 0.94.0" + hashes = [ + "h1:ikFzd4yeJ1LR8ojP2PsZwiK2ZLhxBjRXkEg2HJrI07U=", + "zh:06c8da7d8a048216e825fa7d1e45949c1bda2a5f53f9bb0556b83b6610703fe6", + "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", + "zh:19e82636cfd52a65105e0cf030bc8a0c815082818ef953b84f9b1e349a87318c", + "zh:24af9b7d2f1bb38f480b1aa8cf5e4ecf483bd4403642a9e8a5accbe1ae212feb", + "zh:3b10850e9242bcd00c519ff4140130e8443002fd60b6dff90983e7cb1973b2c3", + "zh:54837a0fa4ddbcf0b8407718f8823b831322deba3bd7ec8492e4578928f50633", + "zh:5cfd6a6b1ca73826a03f8746ef84a5c4059648bc49abf8056c8e0f9b87800a23", + "zh:6ab3bcfef6ff65b4ce76d333b4ad99e5f91991fcf5bddbe1958aadde6ee05eab", + "zh:81b96dc29b055f15e475d8bc32482617a582785949b3c02f44ef15d19951f69c", + "zh:85f478c2fcf10219263462d0f06b5cc41603b1edad813c336e100b3e0a55bfe8", + "zh:9adbb7655fddfe4d4081746d0d7e39c3e8fbf8aa3d8b7d3b5164f30c16a6bd93", + "zh:9c24b39e788283ead8a8ce1f013a47562ff0dc1ccb642a8e18644cbdcda0f1c4", + "zh:a425f28d6a5f6f024cab56c848c55025e84a09db946f1b00a2655d9567251cea", + "zh:f28aa62d2f06e08fe6d18ef9103a8164aa9278540779bebd61120f810c603c6b", + ] +} diff --git a/examples/ske-observability-alerting-kube-state-metrics/main.tf b/examples/ske-observability-alerting-kube-state-metrics/main.tf index 17520b1..0194bc1 100644 --- a/examples/ske-observability-alerting-kube-state-metrics/main.tf +++ b/examples/ske-observability-alerting-kube-state-metrics/main.tf @@ -12,27 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -provider "stackit" { - default_region = "eu01" - service_account_key_path = "" -} - -provider "kubernetes" { - host = yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.server - client_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-certificate-data) - client_key = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-key-data) - cluster_ca_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.certificate-authority-data) -} - -provider "helm" { - kubernetes { - host = yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.server - client_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-certificate-data) - client_key = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-key-data) - cluster_ca_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.certificate-authority-data) - } -} - resource "stackit_ske_cluster" "example" { project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" name = "example" diff --git a/examples/ske-observability-alerting-kube-state-metrics/provider.tf b/examples/ske-observability-alerting-kube-state-metrics/provider.tf new file mode 100644 index 0000000..430bb85 --- /dev/null +++ b/examples/ske-observability-alerting-kube-state-metrics/provider.tf @@ -0,0 +1,51 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_providers { + stackit = { + source = "stackitcloud/stackit" + version = ">= 0.94.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 3.1.0" + } + helm = { + source = "hashicorp/helm" + version = ">= 3.1.1" + } + } +} + +provider "stackit" { + default_region = "eu01" + service_account_key_path = "" +} + +provider "kubernetes" { + host = yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.server + client_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-certificate-data) + client_key = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-key-data) + cluster_ca_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.certificate-authority-data) +} + +provider "helm" { + kubernetes = { + host = yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.server + client_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-certificate-data) + client_key = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-key-data) + cluster_ca_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.certificate-authority-data) + } +} diff --git a/examples/ske-observability-log-alerts/.terraform.lock.hcl b/examples/ske-observability-log-alerts/.terraform.lock.hcl new file mode 100644 index 0000000..3e3b5bf --- /dev/null +++ b/examples/ske-observability-log-alerts/.terraform.lock.hcl @@ -0,0 +1,64 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/helm" { + version = "3.1.1" + constraints = ">= 3.1.1" + hashes = [ + "h1:5b2ojWKT0noujHiweCds37ZreRFRQLNaErdJLusJN88=", + "zh:1a6d5ce931708aec29d1f3d9e360c2a0c35ba5a54d03eeaff0ce3ca597cd0275", + "zh:3411919ba2a5941801e677f0fea08bdd0ae22ba3c9ce3309f55554699e06524a", + "zh:81b36138b8f2320dc7f877b50f9e38f4bc614affe68de885d322629dd0d16a29", + "zh:95a2a0a497a6082ee06f95b38bd0f0d6924a65722892a856cfd914c0d117f104", + "zh:9d3e78c2d1bb46508b972210ad706dd8c8b106f8b206ecf096cd211c54f46990", + "zh:a79139abf687387a6efdbbb04289a0a8e7eaca2bd91cdc0ce68ea4f3286c2c34", + "zh:aaa8784be125fbd50c48d84d6e171d3fb6ef84a221dbc5165c067ce05faab4c8", + "zh:afecd301f469975c9d8f350cc482fe656e082b6ab0f677d1a816c3c615837cc1", + "zh:c54c22b18d48ff9053d899d178d9ffef7d9d19785d9bf310a07d648b7aac075b", + "zh:db2eefd55aea48e73384a555c72bac3f7d428e24147bedb64e1a039398e5b903", + "zh:ee61666a233533fd2be971091cecc01650561f1585783c381b6f6e8a390198a4", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "3.1.0" + constraints = ">= 3.1.0" + hashes = [ + "h1:oodIAuFMikXNmEtil5MQgP4dfSctUBYQiGJfjbsF3NY=", + "zh:0215c5c60be62028c09a2f22458e89cda3ef5830a632299f1d401eb3538874b0", + "zh:09ebb9f442431e278a310a9423f32caf467cb4b3cad3fe59573ca71fa7b14e20", + "zh:0c4e5912f83bb35846ae0a9ae54fc320706ee61894cd21cc6b4181b1c5a2fa5c", + "zh:1678c982853ad461e65ccb5e79d585e13ed109dd47dab2a66d3a7a304faeef65", + "zh:1c050a5c15e330457a9c18caacf61a923c59d663e13f2962e4b32f04fef523a0", + "zh:2c55bcec83be58ec132c7cb0a1ac644758b800d794fdc636d53a0eada0358a3a", + "zh:a062bb0aa316c08d8460c66a5d68da71da40de5d3bc3b31abcf3a1a9a19650f1", + "zh:a26fdea0afaa9b247c73c0b42843ca51ba7db0ac2571f9d3d50dcabd20ca1b98", + "zh:c872c9385a78d502bf5823d61cd3bb0f9a0585030e025eb12585c83451beeaa1", + "zh:f180879af931182beee4c8c0d9dab62b81d86f17ddcbe3786ef4c7cec9163a4e", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f70f5789264069e0eef06f9b5d5fde955ef7206f7d446d1ce51a4c37a3f3e02f", + ] +} + +provider "registry.terraform.io/stackitcloud/stackit" { + version = "0.94.0" + constraints = ">= 0.94.0" + hashes = [ + "h1:ikFzd4yeJ1LR8ojP2PsZwiK2ZLhxBjRXkEg2HJrI07U=", + "zh:06c8da7d8a048216e825fa7d1e45949c1bda2a5f53f9bb0556b83b6610703fe6", + "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", + "zh:19e82636cfd52a65105e0cf030bc8a0c815082818ef953b84f9b1e349a87318c", + "zh:24af9b7d2f1bb38f480b1aa8cf5e4ecf483bd4403642a9e8a5accbe1ae212feb", + "zh:3b10850e9242bcd00c519ff4140130e8443002fd60b6dff90983e7cb1973b2c3", + "zh:54837a0fa4ddbcf0b8407718f8823b831322deba3bd7ec8492e4578928f50633", + "zh:5cfd6a6b1ca73826a03f8746ef84a5c4059648bc49abf8056c8e0f9b87800a23", + "zh:6ab3bcfef6ff65b4ce76d333b4ad99e5f91991fcf5bddbe1958aadde6ee05eab", + "zh:81b96dc29b055f15e475d8bc32482617a582785949b3c02f44ef15d19951f69c", + "zh:85f478c2fcf10219263462d0f06b5cc41603b1edad813c336e100b3e0a55bfe8", + "zh:9adbb7655fddfe4d4081746d0d7e39c3e8fbf8aa3d8b7d3b5164f30c16a6bd93", + "zh:9c24b39e788283ead8a8ce1f013a47562ff0dc1ccb642a8e18644cbdcda0f1c4", + "zh:a425f28d6a5f6f024cab56c848c55025e84a09db946f1b00a2655d9567251cea", + "zh:f28aa62d2f06e08fe6d18ef9103a8164aa9278540779bebd61120f810c603c6b", + ] +} diff --git a/examples/ske-observability-log-alerts/main.tf b/examples/ske-observability-log-alerts/main.tf index 21b3e6a..1be4fc0 100644 --- a/examples/ske-observability-log-alerts/main.tf +++ b/examples/ske-observability-log-alerts/main.tf @@ -12,27 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -provider "stackit" { - default_region = "eu01" - service_account_key_path = "" -} - -provider "kubernetes" { - host = yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.server - client_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-certificate-data) - client_key = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-key-data) - cluster_ca_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.certificate-authority-data) -} - -provider "helm" { - kubernetes { - host = yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.server - client_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-certificate-data) - client_key = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-key-data) - cluster_ca_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.certificate-authority-data) - } -} - resource "stackit_ske_cluster" "example" { project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" name = "example" diff --git a/examples/ske-observability-log-alerts/provider.tf b/examples/ske-observability-log-alerts/provider.tf new file mode 100644 index 0000000..430bb85 --- /dev/null +++ b/examples/ske-observability-log-alerts/provider.tf @@ -0,0 +1,51 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_providers { + stackit = { + source = "stackitcloud/stackit" + version = ">= 0.94.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 3.1.0" + } + helm = { + source = "hashicorp/helm" + version = ">= 3.1.1" + } + } +} + +provider "stackit" { + default_region = "eu01" + service_account_key_path = "" +} + +provider "kubernetes" { + host = yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.server + client_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-certificate-data) + client_key = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-key-data) + cluster_ca_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.certificate-authority-data) +} + +provider "helm" { + kubernetes = { + host = yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.server + client_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-certificate-data) + client_key = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).users.0.user.client-key-data) + cluster_ca_certificate = base64decode(yamldecode(stackit_ske_kubeconfig.example.kube_config).clusters.0.cluster.certificate-authority-data) + } +} diff --git a/examples/ske-stackit-sfs-integration/.terraform.lock.hcl b/examples/ske-stackit-sfs-integration/.terraform.lock.hcl index 75c9e75..d3f19c1 100644 --- a/examples/ske-stackit-sfs-integration/.terraform.lock.hcl +++ b/examples/ske-stackit-sfs-integration/.terraform.lock.hcl @@ -5,6 +5,7 @@ provider "registry.terraform.io/stackitcloud/stackit" { version = "0.79.0" constraints = "0.79.0" hashes = [ + "h1:AB51ok4llxeTmkVadjYpsafPbzSU5xEHLzcVBuVHxqc=", "h1:l7AeT3WWi/u7QB7E1SaksYc5VjU9JS2LYc4OnavI3kw=", "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", "zh:1eb8276c0d8a4b5b92534020df0cb270ed7c4d91dfed6db089ee775b50a8f5e3", diff --git a/examples/stackit-landing-zone/README.md b/examples/stackit-landing-zone/README.md new file mode 100644 index 0000000..5173e22 --- /dev/null +++ b/examples/stackit-landing-zone/README.md @@ -0,0 +1,4 @@ +# STACKIT Landing Zone + +For the full Terraform Landing Zone implementation, please visit: +[STACKIT Terraform Landing Zone Repository](https://github.com/stackitcloud/stackit-landing-zone) diff --git a/examples/vpn-usecases/README.md b/examples/vpn-usecases/README.md new file mode 100644 index 0000000..27e0755 --- /dev/null +++ b/examples/vpn-usecases/README.md @@ -0,0 +1,7 @@ +# VPN Usecases + +> ⚠️ Note: Currently, we are still leveraging the restful provider to roll out managed VPN resources. Native integration for the STACKIT Terraform provider is a work in progress. We will update these examples once it is released. + +- [`STACKIT-STACKIT`](stackit-stackit) +- [`STACKIT-GCP`](stackit-gcp) +- [`STACKIT-AZURE`](stackit-azure) diff --git a/examples/vpn-usecases/module/stackit-sna-with-debug-machine/README.md b/examples/vpn-usecases/module/stackit-sna-with-debug-machine/README.md new file mode 100644 index 0000000..509f3de --- /dev/null +++ b/examples/vpn-usecases/module/stackit-sna-with-debug-machine/README.md @@ -0,0 +1,70 @@ +# SNA with test-machine module + +This module is used to quickly spin up a sna with a test virtual machine. We use this module to debug vpn connectivity. + +> ⚠️ **SECURITY WARNING** +> Be careful: By default, **port security is disabled** on the network interface to allow unrestricted traffic for debugging purposes. **Do not use this module in a production environment**. + + + +## Requirements + +| Name | Version | +| ------------------------------------------------------------------ | -------- | +| [stackit](#requirement_stackit) | >=0.95.0 | + +## Providers + +| Name | Version | +| ------------------------------------------------------------ | -------- | +| [stackit](#provider_stackit) | >=0.95.0 | + +## Modules + +No modules. + +## Resources + +| Name | Type | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | +| [stackit_network.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/network) | resource | +| [stackit_network_area.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/network_area) | resource | +| [stackit_network_area_region.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/network_area_region) | resource | +| [stackit_network_interface.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/network_interface) | resource | +| [stackit_public_ip.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/public_ip) | resource | +| [stackit_resourcemanager_project.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/resourcemanager_project) | resource | +| [stackit_server.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/server) | resource | +| [stackit_volume.this](https://registry.terraform.io/providers/stackitcloud/stackit/latest/docs/resources/volume) | resource | + +## Inputs + +| Name | Description | Type | Default | Required | +| --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | -------------- | ---------------------------------------- | :------: | +| [machine_availability_zone](#input_machine_availability_zone) | The availability zone (e.g. eu01-1) | `string` | n/a | yes | +| [machine_disk_performance_class](#input_machine_disk_performance_class) | Storage performance class | `string` | `"storage_premium_perf4"` | no | +| [machine_disk_size](#input_machine_disk_size) | Boot volume size in GB | `number` | `20` | no | +| [machine_image_id](#input_machine_image_id) | Image UUID (Default: Debian 12) | `string` | `"c751cde7-e648-4f81-9722-ce9c7848bed0"` | no | +| [machine_ipv4_prefix](#input_machine_ipv4_prefix) | The IPv4 prefix for the test machine's network (CIDR notation). This must be a subnet within the defined SNA network ranges. | `string` | n/a | yes | +| [machine_name](#input_machine_name) | name of the stackit test machine | `string` | n/a | yes | +| [machine_network_name](#input_machine_network_name) | The name of the network where the test machine will be connected. | `string` | n/a | yes | +| [machine_type](#input_machine_type) | Flavor of the machine | `string` | `"c2i.1"` | no | +| [sna_default_nameserver](#input_sna_default_nameserver) | A list of STACKIT SNA default nameservers (IP addresses). | `list(string)` |
[| no | +| [sna_name](#input_sna_name) | The name of the STACKIT Network Area (SNA). | `string` | n/a | yes | +| [sna_network_range_prefix](#input_sna_network_range_prefix) | A list of STACKIT SNA network range prefixes in CIDR notation. | `list(string)` |
"1.1.1.1"
]
[| no | +| [sna_transfer_range](#input_sna_transfer_range) | The STACKIT SNA transfer range in CIDR notation. | `string` | `"172.16.0.0/16"` | no | +| [stackit_admin_email](#input_stackit_admin_email) | The email address of the project administrator. | `string` | n/a | yes | +| [stackit_org_id](#input_stackit_org_id) | The STACKIT Organization ID (UUID). | `string` | n/a | yes | +| [stackit_project_name](#input_stackit_project_name) | The name of the STACKIT project where the managed VPN and test machine will be deployed. | `string` | n/a | yes | + +## Outputs + +| Name | Description | +| ----------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | +| [machine_network_ipv4](#output_machine_network_ipv4) | The IPv4 prefix of the machine's network. | +| [machine_private_ipv4](#output_machine_private_ipv4) | The private IP address of the test machine. | +| [machine_public_ip](#output_machine_public_ip) | The public IP address of the test machine. | +| [project_id](#output_project_id) | The ID of the STACKIT project. | +| [sna_id](#output_sna_id) | The ID of the STACKIT Network Area. | +| [sna_network_range](#output_sna_network_range) | The network ranges (sna-ipv4) of the STACKIT Network Area. | + + diff --git a/examples/vpn-usecases/module/stackit-sna-with-debug-machine/debug-user.yml b/examples/vpn-usecases/module/stackit-sna-with-debug-machine/debug-user.yml new file mode 100644 index 0000000..865ffb5 --- /dev/null +++ b/examples/vpn-usecases/module/stackit-sna-with-debug-machine/debug-user.yml @@ -0,0 +1,25 @@ +#cloud-config +# --------------------------------------------------------------------------- +# Example cloud-init for Linux instances (RHEL / Debian). +# Creates a local admin user for initial access. +# +# IMPORTANT: Replace the password hash below with a hash of your own +# secure password before deploying. Never use a shared or well-known +# default password in production. +# +# Generate a SHA-512 hash on Linux/macOS: +# openssl passwd -6 "YourPassword" +# --------------------------------------------------------------------------- +users: + - name: debug + groups: sudo + shell: /bin/bash + sudo: ["ALL=(ALL) NOPASSWD:ALL"] + lock_passwd: false + # debug123 + passwd: "$6$dIIA5b1oK7qi89.P$MH9SSMtnzCo8QvvUnVoCE5e1c7FY0NUgB4dpsv5JDq9zpRDiTpfiYtM5DitiJIuQWvZ7T1emTTgKaBufayaIW." + +chpasswd: + expire: false + +ssh_pwauth: true diff --git a/examples/vpn-usecases/module/stackit-sna-with-debug-machine/main.tf b/examples/vpn-usecases/module/stackit-sna-with-debug-machine/main.tf new file mode 100644 index 0000000..a8f09c4 --- /dev/null +++ b/examples/vpn-usecases/module/stackit-sna-with-debug-machine/main.tf @@ -0,0 +1,96 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +resource "stackit_network_area" "this" { + name = var.sna_name + organization_id = var.stackit_org_id + labels = { + "preview/routingtables" = "true" + } +} + +resource "stackit_network_area_region" "this" { + organization_id = var.stackit_org_id + network_area_id = stackit_network_area.this.network_area_id + ipv4 = { + transfer_network = var.sna_transfer_range + network_ranges = [ + for prefix in var.sna_network_range_prefix : { + prefix = prefix + } + ] + default_nameservers = var.sna_default_nameserver + } +} + +resource "stackit_resourcemanager_project" "this" { + parent_container_id = var.stackit_org_id + name = var.stackit_project_name + owner_email = var.stackit_admin_email + labels = { + "networkArea" = stackit_network_area.this.network_area_id + } +} + +resource "stackit_volume" "this" { + project_id = stackit_resourcemanager_project.this.project_id + name = "${var.machine_name}-volume" + availability_zone = var.machine_availability_zone + size = var.machine_disk_size + performance_class = var.machine_disk_performance_class + source = { + type = "image" + id = var.machine_image_id + } +} + +resource "stackit_network" "this" { + name = var.machine_network_name + project_id = stackit_resourcemanager_project.this.project_id + ipv4_prefix = var.machine_ipv4_prefix + ipv4_nameservers = var.sna_default_nameserver +} + +resource "stackit_network_interface" "this" { + project_id = stackit_resourcemanager_project.this.project_id + network_id = stackit_network.this.network_id + security = false +} + +resource "stackit_server" "this" { + project_id = stackit_resourcemanager_project.this.project_id + name = var.machine_name + availability_zone = var.machine_availability_zone + machine_type = var.machine_type + + boot_volume = { + source_type = "volume" + source_id = stackit_volume.this.volume_id + } + + agent = { + provisioning_policy = "ALWAYS" + } + + network_interfaces = [ + stackit_network_interface.this.network_interface_id + ] + + user_data = file("${path.module}/debug-user.yml") +} + +resource "stackit_public_ip" "this" { + project_id = stackit_resourcemanager_project.this.project_id + network_interface_id = stackit_network_interface.this.network_interface_id +} diff --git a/examples/vpn-usecases/module/stackit-sna-with-debug-machine/outputs.tf b/examples/vpn-usecases/module/stackit-sna-with-debug-machine/outputs.tf new file mode 100644 index 0000000..ec2f79d --- /dev/null +++ b/examples/vpn-usecases/module/stackit-sna-with-debug-machine/outputs.tf @@ -0,0 +1,43 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +output "sna_id" { + description = "The ID of the STACKIT Network Area." + value = stackit_network_area.this.network_area_id +} + +output "project_id" { + description = "The ID of the STACKIT project." + value = stackit_resourcemanager_project.this.project_id +} + +output "machine_public_ip" { + description = "The public IP address of the test machine." + value = stackit_public_ip.this.ip +} + +output "machine_private_ipv4" { + description = "The private IP address of the test machine." + value = stackit_network_interface.this.ipv4 +} + +output "machine_network_ipv4" { + description = "The IPv4 prefix of the machine's network." + value = stackit_network.this.ipv4_prefix +} + +output "sna_network_range" { + description = "The network ranges (sna-ipv4) of the STACKIT Network Area." + value = stackit_network_area_region.this.ipv4.network_ranges +} diff --git a/examples/vpn-usecases/module/stackit-sna-with-debug-machine/provider.tf b/examples/vpn-usecases/module/stackit-sna-with-debug-machine/provider.tf new file mode 100644 index 0000000..edbbfce --- /dev/null +++ b/examples/vpn-usecases/module/stackit-sna-with-debug-machine/provider.tf @@ -0,0 +1,22 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_providers { + stackit = { + source = "stackitcloud/stackit" + version = ">=0.95.0" + } + } +} diff --git a/examples/vpn-usecases/module/stackit-sna-with-debug-machine/variables.tf b/examples/vpn-usecases/module/stackit-sna-with-debug-machine/variables.tf new file mode 100644 index 0000000..a3fce06 --- /dev/null +++ b/examples/vpn-usecases/module/stackit-sna-with-debug-machine/variables.tf @@ -0,0 +1,138 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +variable "stackit_org_id" { + description = "The STACKIT Organization ID (UUID)." + type = string + validation { + condition = can(regex("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", var.stackit_org_id)) + error_message = "The stackit_org_id must be a valid UUID." + } +} + +variable "stackit_project_name" { + description = "The name of the STACKIT project where the managed VPN and test machine will be deployed." + type = string + validation { + condition = length(var.stackit_project_name) >= 1 && length(var.stackit_project_name) <= 63 + error_message = "The project name must be between 1 and 63 characters long." + } +} + +variable "stackit_admin_email" { + description = "The email address of the project administrator." + type = string + validation { + condition = can(regex("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", var.stackit_admin_email)) + error_message = "The stackit_admin_email must be a valid email address." + } +} + +variable "sna_name" { + description = "The name of the STACKIT Network Area (SNA)." + type = string +} + +variable "sna_transfer_range" { + description = "The STACKIT SNA transfer range in CIDR notation." + type = string + default = "172.16.0.0/16" + validation { + condition = can(cidrnetmask(var.sna_transfer_range)) + error_message = "The sna_transfer_range must be a valid CIDR notation." + } +} + +variable "sna_network_range_prefix" { + description = "A list of STACKIT SNA network range prefixes in CIDR notation." + type = list(string) + default = ["10.28.0.0/16"] + validation { + condition = alltrue([for r in var.sna_network_range_prefix : can(cidrnetmask(r))]) + error_message = "All elements in sna_network_range_prefix must be valid CIDR notations." + } +} + +variable "sna_default_nameserver" { + description = "A list of STACKIT SNA default nameservers (IP addresses)." + type = list(string) + default = ["1.1.1.1"] + validation { + condition = alltrue([for ns in var.sna_default_nameserver : can(regex("^((25[0-5]|(2[0-4]|1\\d|[1-9]|)\\d)\\.?\\b){4}$", ns))]) + error_message = "All elements in sna_default_nameserver must be valid IP addresses." + } +} + +variable "machine_network_name" { + description = "The name of the network where the test machine will be connected." + type = string +} + +variable "machine_ipv4_prefix" { + description = "The IPv4 prefix for the test machine's network (CIDR notation). This must be a subnet within the defined SNA network ranges." + type = string + validation { + condition = can(cidrnetmask(var.machine_ipv4_prefix)) + error_message = "The machine_ipv4_prefix must be a valid CIDR notation." + } +} + +variable "machine_name" { + type = string + description = "name of the stackit test machine" +} + +variable "machine_availability_zone" { + description = "The availability zone (e.g. eu01-1)" + type = string + + validation { + condition = can(regex("^[a-z]{2}[0-9]{2}-[a-zA-Z0-9]+$", var.machine_availability_zone)) + error_message = "The availability zone must follow the STACKIT pattern (e.g., eu01-1, eu01-m)." + } +} + +variable "machine_type" { + description = "Flavor of the machine" + type = string + default = "c2i.1" +} + +variable "machine_image_id" { + description = "Image UUID (Default: Debian 12)" + type = string + default = "c751cde7-e648-4f81-9722-ce9c7848bed0" + + validation { + condition = can(regex("^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$", var.machine_image_id)) + error_message = "The image_id must be a valid UUID." + } +} + +variable "machine_disk_size" { + description = "Boot volume size in GB" + type = number + default = 20 + + validation { + condition = var.machine_disk_size >= 1 + error_message = "The disk_size must be at least 1 GB." + } +} + +variable "machine_disk_performance_class" { + description = "Storage performance class" + type = string + default = "storage_premium_perf4" +} diff --git a/examples/vpn-usecases/stackit-azure/.terraform.lock.hcl b/examples/vpn-usecases/stackit-azure/.terraform.lock.hcl new file mode 100644 index 0000000..e793dcf --- /dev/null +++ b/examples/vpn-usecases/stackit-azure/.terraform.lock.hcl @@ -0,0 +1,105 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/azurerm" { + version = "4.72.0" + constraints = "4.72.0" + hashes = [ + "h1:QYnPAHT/PYheOOZz52ucHqw/ZO9PxWyPLtO7UD/jSMg=", + "zh:073472587c3752e89738522814d2b4eb2fd69eb2cb19c5a5ead3c7d2eabdc279", + "zh:1950effc0c315b6002c8cb6327b94fe59bda210e699367d9727bc66490d651d2", + "zh:47c990db75658525de57c8955a05b4752b88f3a900fffac0e7661d4a749e94f2", + "zh:610f2cbd6fab76750d8b093f03beabbb7162dc8c6affe0109f534ce240b3ff0f", + "zh:6739d645fe548c5a489d711f7748f32368cf68d723d2c59d3f2e21456304d692", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:a277ab095cc8aff3aede9e43eca2a699936472ef90abb272adf3daa609eb9141", + "zh:b1fdcdaf926c86de0d884beda90d78cb94a42ddede03a1f0b92c36b321d4f07e", + "zh:c003f1f15e52c54e189301ae2c7d8dd65acb2e5a7527d201355f2757b5465ba9", + "zh:c45f2d2206c0f8f71f207cd39eec73da9619d35932bbe1a5b8be7679c50a151e", + "zh:d7040d8ec295481bc1d30346ed7f3075c40ede87c0fedf1db34dd91c1c367a10", + "zh:e595f0b870cd5fd5debdc926fc1740201d2b66188b9b132dc598bdd6444e7348", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.9.0" + hashes = [ + "h1:OO+IuvQJSPmWdN8AyyIEvPJbLvDQpgX/zbktoa9KsJE=", + "zh:161ad0bd9a75768c82f53fb6e7172a9d8be2d4889b012645a34795031aaf1bf1", + "zh:19dc9a5b17729725ccfc4f45b0500af0ee5bc6b6b160c7adb8f2bf617d2c80ea", + "zh:269eda8fe42daa7974d5a34d166c3ba9defe80cde86c01e4dadcfdf2e1f05e5f", + "zh:373f7c65566f8f2cc7f45d698654feb9d988996957e1266a69ca00c52d6d16d0", + "zh:5599d16804c41c83009ec621b6d6b6f74e102f5827678a4750f8809055546b61", + "zh:583be0440469a22bff70dcfa56593b01566860b29607437264adb51060cf46fc", + "zh:5f211d8ec3f2e1f414870d9584bfe26e6995560ef81c748f8447a48164767398", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7b547fd16216761ef86efc3ed516ac5ac0c5c42b7c7eb24a08cef2d93f69ed5e", + "zh:7e7c0679daf2a382151d05068c8c3f0dae6b7b7dccf818827b73dd08638df2ef", + "zh:8089dec888a8038b9b4fb23b3df7e1057293dbc5b60b42cc47ff690d69d4b61b", + "zh:c51f15a031edfd6f23ce8ced3446ca7f8d8d647e2499890d7d5d10d5016d7257", + "zh:c94784f005708890dc6895afd53636ec00ec1e430b15d41e5aebfb1d4b39bd04", + ] +} + +provider "registry.terraform.io/hashicorp/time" { + version = "0.14.0" + hashes = [ + "h1:/hlxsUpuN/lvPTNL9+NyVGsOyRsK5NsxwFMsj5CdOp4=", + "zh:12abfd6b800e4d7fa6db7310dec8ffd440b31993861ef188c7ed5260b3073937", + "zh:23005521e800bb19e1597bf755c5f70d675d30b685d4255001ed5fa47d9df3f1", + "zh:2fea249b582ae97cd1cc10385187ea50993bb47c28cc5df0305e57ceaabf0a10", + "zh:322018d3b987b7aad08697178029a2bb667bed699e88328f0c89c52a2fd41341", + "zh:32a08e98fce2d273cb9b2c89d6c54727cc9f0a32e15bfd896be4e02cc6b48f95", + "zh:3db89aabd0e619616bd4b0f8b373a7586dfe60feffcea12a84a0bdbc445714b3", + "zh:7488f56c81d742dc020f29063626c8f07ca188aa97be61e7307e8d62397020a2", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:7cb4067f2e7559b13f7562ef722f948950901eb37834873e98360ab28f66e9d7", + "zh:9d552c8345f61e1b7db8e725144981345f18ac1014d58d6f5ddf0928a195fffb", + "zh:a8e69fb6b97fc9d86fb19a9f4d42abe33c4a68e700b15387ce2e17d2b9934bed", + "zh:aeeb900eb8dd0f790c60ea5c0e0c8d42bd6e4a54f391681d4decca15b544394b", + "zh:c239c619101a8c95e1f14061eb973c57a8d15fa0e68878ced5bbd76858ee5b79", + ] +} + +provider "registry.terraform.io/magodo/restful" { + version = "0.25.2" + hashes = [ + "h1:gvoDTFfxp7n1B4Wsnx9IC7Ku8g8tdVR4mCC6TDX0Mws=", + "zh:0513ff62fce41a59462f39e1c4636f3c87e6f8d24ee579075900d3e0f57f6992", + "zh:1a3e39e6b8c7fd0f3983730944a029db8f00557922e337cff0567a07c5e74b45", + "zh:2527c96fcc45458efc9eca1c66cee98269d80693b571c57baee783402bfbaa28", + "zh:50cec9afe8b55629d1c94d477b26ff95de8cc8e3304f6c2bfc5dad3bccc6decc", + "zh:89e94c0f312d0ef4213b46ee776a27f6a5d114520c08a4716f4fee4c26c16f91", + "zh:9a9762ebaf9567a4aa34a1911f051527696241679e087137fcc7821e52b66483", + "zh:a065be3488e24928199904f4a496974c03fdcf2b06fccf016e405b3068d5ef76", + "zh:c62a1a6fb3c5135451f68ea4ed1f66d999ab654323d10526756e83f6f77d6bdf", + "zh:cf01364f89b713dc10eb87098839317e6f2de222bec2597923cddbb07bdd9c13", + "zh:dc0ac6a1e5e3199e1d35fb49f9de1d9325caa3c0d3e87ea8128295e19ac941c3", + "zh:e55cf6e8230f081b7c8ade592c14f1b8b45ee0aaa14c2bde2da9531d819a4392", + "zh:f333748916e68050c8935d760d6b9b469dd76eb94363af93562cbd076dba6ff5", + "zh:f809ab383cca0a5f83072981c64208cbd7fa67e986a86ee02dd2c82333221e32", + "zh:fdfdca8b7976c1a8b1b6a3589b4bfec277beb6dfb40c5568271d42f0b2f88a9d", + ] +} + +provider "registry.terraform.io/stackitcloud/stackit" { + version = "0.95.0" + constraints = ">= 0.87.0, >= 0.95.0" + hashes = [ + "h1:sKmc6SGKEFglXKLMtOluJkFm7tzQZKQV3/QxUbHug1E=", + "zh:023edbb8ca984233bb51605a9005d4f7cb3365f0b11ddd68d911a1e30ccf64be", + "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", + "zh:1fc43ed3055c4912e5b3ae2eba49dd5407beaa9ba6617612f317543f7d26ccd7", + "zh:31e587a9f279661b74b139e2a964a7d1c54a4073d27d21c2f948e0e7ba4c0d04", + "zh:37427a23800dff84c1b89d4985cb935c0112c59acd716d8920c160221c459061", + "zh:3a575f5c7d1252d99aea9187923087e1d483b2b34e42c9f058f557ec28c45d84", + "zh:44c7ee340e1a09d6f9a9873959f8283f0d73aee4a8c884f7b36985f943874b65", + "zh:4fab8fe953a0d4c21589cd36d23afe072c6403e37620c82839f9f829139cbbbf", + "zh:69fc061b3c7ea82d9e9a31d3665a535f6bb9dc3d6ff5b466f940d3d04a105e19", + "zh:85ee00442eff70ea103a96276efb5e1485b661b0a1db08bcdbd28b11b1f966e6", + "zh:9761ef1321c93cb3e4bc2499995b3e7ae910e2ae68b3228164dea73e9687ddb5", + "zh:b158a4e4726a4d4c9f61c5dc71abb4ca3a621269e1d7af88ab36d34c3bcec66f", + "zh:da37df9a426d83da8f6c1340104a6b9a7eef4a7e2589d0b70a89c574a1b3cc78", + "zh:e6421b9a351b2c9b2ab2341f2c07d863eb2ed055b847ea839de96b0fd62baf97", + ] +} diff --git a/examples/vpn-usecases/stackit-azure/010-provider.tf b/examples/vpn-usecases/stackit-azure/010-provider.tf new file mode 100644 index 0000000..88f7674 --- /dev/null +++ b/examples/vpn-usecases/stackit-azure/010-provider.tf @@ -0,0 +1,54 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +terraform { + required_providers { + stackit = { + source = "stackitcloud/stackit" + version = ">=0.95.0" + } + restful = { + source = "magodo/restful" + } + azurerm = { + source = "hashicorp/azurerm" + version = "4.72.0" + } + } +} + +provider "stackit" { + default_region = var.stackit_region + service_account_key_path = var.stackit_service_account_key_path + enable_beta_resources = true +} + +provider "azurerm" { + features {} + subscription_id = var.azure_subscription_id +} + +ephemeral "stackit_access_token" "this" {} + +provider "restful" { + alias = "stackit" + base_url = "https://vpn.api.eu01.stackit.cloud" + security = { + http = { + token = { + token = ephemeral.stackit_access_token.this.access_token + } + } + } +} diff --git a/examples/vpn-usecases/stackit-azure/020-variables.tf b/examples/vpn-usecases/stackit-azure/020-variables.tf new file mode 100644 index 0000000..ae3c32e --- /dev/null +++ b/examples/vpn-usecases/stackit-azure/020-variables.tf @@ -0,0 +1,34 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +variable "stackit_org_id" { + type = string +} + +variable "stackit_region" { + type = string + default = "eu01" +} + +variable "stackit_service_account_key_path" { + type = string +} + +variable "azure_subscription_id" { + type = string +} + +variable "stackit_admin_email" { + type = string +} diff --git a/examples/vpn-usecases/stackit-azure/030-stackit-azure-vpn.tf b/examples/vpn-usecases/stackit-azure/030-stackit-azure-vpn.tf new file mode 100644 index 0000000..2d3d7a2 --- /dev/null +++ b/examples/vpn-usecases/stackit-azure/030-stackit-azure-vpn.tf @@ -0,0 +1,376 @@ +# Copyright 2026 Schwarz Digits Cloud GmbH & Co. KG +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# STACKIT Side (vpn-sna-01) +module "vpn_sna_01" { + source = "../module/stackit-sna-with-debug-machine" + machine_availability_zone = "eu01-1" + machine_ipv4_prefix = "10.10.10.0/24" + machine_network_name = "vpn-sna-01" + sna_name = "vpn-sna-01" + machine_name = "vpn-sna-01" + stackit_admin_email = var.stackit_admin_email + stackit_org_id = var.stackit_org_id + stackit_project_name = "vpn-sna-01" + sna_network_range_prefix = [ + "10.10.0.0/16" + ] +} + +resource "restful_resource" "vpn_01_gateway" { + provider = restful.stackit + path = "/v1/projects/${module.vpn_sna_01.project_id}/regions/eu01/gateways" + body = { + availabilityZones = { + tunnel1 = "eu01-1" + tunnel2 = "eu01-2" + } + bgp = { + localAsn = 64512 + overrideAdvertisedRoutes = ["10.10.0.0/16"] + } + displayName = "vpn01" + labels = null + planId = "p500" + routingType = "BGP_ROUTE_BASED" + } + + read_path = "$(path)/$(body.id)" + update_path = "$(path)/$(body.id)" + update_method = "PUT" + delete_path = "$(path)/$(body.id)" + delete_method = "DELETE" +} + +data "restful_resource" "vpn_01_gateway_status" { + provider = restful.stackit + id = "${restful_resource.vpn_01_gateway.id}/status" +} + +resource "random_password" "vpn_psk" { + length = 32 + special = false +} + +# Azure Side +resource "azurerm_resource_group" "rg" { + name = "rg-vpn-test" + location = "West Europe" +} + +# 1. Azure VNet and Subnets +resource "azurerm_virtual_network" "azure_vnet" { + name = "azure-vpn-network" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + address_space = ["10.11.0.0/16"] +} + +resource "azurerm_subnet" "azure_gateway_subnet" { + name = "GatewaySubnet" # MUST be exactly named GatewaySubnet + resource_group_name = azurerm_resource_group.rg.name + virtual_network_name = azurerm_virtual_network.azure_vnet.name + address_prefixes = ["10.11.0.0/24"] +} + +resource "azurerm_subnet" "azure_vm_subnet" { + name = "vm-subnet" + resource_group_name = azurerm_resource_group.rg.name + virtual_network_name = azurerm_virtual_network.azure_vnet.name + address_prefixes = ["10.11.1.0/24"] +} + +# 2. Azure Public IPs (2 required for Active-Active HA VPN) +resource "azurerm_public_ip" "azure_gw_pip1" { + name = "azure-gw-pip1" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + allocation_method = "Static" + sku = "Standard" + zones = ["1", "2", "3"] + + lifecycle { + ignore_changes = [domain_name_label] + } +} + +resource "azurerm_public_ip" "azure_gw_pip2" { + name = "azure-gw-pip2" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + allocation_method = "Static" + sku = "Standard" + zones = ["1", "2", "3"] + + lifecycle { + ignore_changes = [domain_name_label] + } +} + +# 3. Azure HA VPN Gateway +resource "azurerm_virtual_network_gateway" "azure_gateway" { + name = "azure-ha-vpn" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + + type = "Vpn" + vpn_type = "RouteBased" + active_active = true + bgp_enabled = true + sku = "VpnGw1AZ" + + bgp_settings { + asn = 64513 # Azure's local ASN + peering_addresses { + ip_configuration_name = "vnetGatewayConfig1" + apipa_addresses = ["169.254.21.2"] + } + peering_addresses { + ip_configuration_name = "vnetGatewayConfig2" + apipa_addresses = ["169.254.21.6"] + } + } + + ip_configuration { + name = "vnetGatewayConfig1" + public_ip_address_id = azurerm_public_ip.azure_gw_pip1.id + private_ip_address_allocation = "Dynamic" + subnet_id = azurerm_subnet.azure_gateway_subnet.id + } + + ip_configuration { + name = "vnetGatewayConfig2" + public_ip_address_id = azurerm_public_ip.azure_gw_pip2.id + private_ip_address_allocation = "Dynamic" + subnet_id = azurerm_subnet.azure_gateway_subnet.id + } +} + +# 4. Azure Local Network Gateways (Represents the 2 STACKIT Tunnels) +resource "azurerm_local_network_gateway" "stackit_tunnel1" { + name = "stackit-tunnel-1" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + gateway_address = data.restful_resource.vpn_01_gateway_status.output.tunnels[0].publicIP + + bgp_settings { + asn = 64512 + bgp_peering_address = "169.254.21.1" + } +} + +resource "azurerm_local_network_gateway" "stackit_tunnel2" { + name = "stackit-tunnel-2" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + gateway_address = data.restful_resource.vpn_01_gateway_status.output.tunnels[1].publicIP + + bgp_settings { + asn = 64512 + bgp_peering_address = "169.254.21.5" + } +} + +# 5. Azure VPN Connections +resource "azurerm_virtual_network_gateway_connection" "azure_tunnel1" { + name = "conn-to-stackit-tunnel1" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + + type = "IPsec" + virtual_network_gateway_id = azurerm_virtual_network_gateway.azure_gateway.id + local_network_gateway_id = azurerm_local_network_gateway.stackit_tunnel1.id + shared_key = random_password.vpn_psk.result + enable_bgp = true + + ipsec_policy { + ike_encryption = "GCMAES256" + ike_integrity = "SHA256" + ipsec_encryption = "GCMAES256" + ipsec_integrity = "GCMAES256" + dh_group = "DHGroup14" + pfs_group = "PFS14" + sa_lifetime = 3600 + sa_datasize = 102400000 + } +} + +resource "azurerm_virtual_network_gateway_connection" "azure_tunnel2" { + name = "conn-to-stackit-tunnel2" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + + type = "IPsec" + virtual_network_gateway_id = azurerm_virtual_network_gateway.azure_gateway.id + local_network_gateway_id = azurerm_local_network_gateway.stackit_tunnel2.id + shared_key = random_password.vpn_psk.result + enable_bgp = true + + ipsec_policy { + ike_encryption = "GCMAES256" + ike_integrity = "SHA256" + ipsec_encryption = "GCMAES256" + ipsec_integrity = "GCMAES256" + dh_group = "DHGroup14" + pfs_group = "PFS14" + sa_lifetime = 3600 + sa_datasize = 102400000 + } +} + +# Connection from STACKIT to Azure +resource "restful_resource" "vpn_01_connection" { + provider = restful.stackit + path = "${restful_resource.vpn_01_gateway.id}/connections" + body = { + displayName = "conn-to-azure" + tunnel1 = { + bgp = { + remoteAsn = 64513 + } + peering = { + localAddress = "169.254.21.1" + remoteAddress = "169.254.21.2" + } + phase1 = { + dhGroups = ["modp2048"] + encryptionAlgorithms = ["aes256gcm16"] + integrityAlgorithms = ["sha2_256"] + } + phase2 = { + dhGroups = ["modp2048"] + encryptionAlgorithms = ["aes256gcm16"] + integrityAlgorithms = ["sha2_256"] + } + preSharedKey = random_password.vpn_psk.result + remoteAddress = azurerm_public_ip.azure_gw_pip1.ip_address + } + tunnel2 = { + bgp = { + remoteAsn = 64513 + } + peering = { + localAddress = "169.254.21.5" + remoteAddress = "169.254.21.6" + } + phase1 = { + dhGroups = ["modp2048"] + encryptionAlgorithms = ["aes256gcm16"] + integrityAlgorithms = ["sha2_256"] + } + phase2 = { + dhGroups = ["modp2048"] + encryptionAlgorithms = ["aes256gcm16"] + integrityAlgorithms = ["sha2_256"] + } + preSharedKey = random_password.vpn_psk.result + remoteAddress = azurerm_public_ip.azure_gw_pip2.ip_address + } + } + + lifecycle { + ignore_changes = [ + body.tunnel1.preSharedKey, + body.tunnel2.preSharedKey + ] + } + + read_path = "$(path)/$(body.id)" + update_path = "$(path)/$(body.id)" + update_method = "PUT" + delete_path = "$(path)/$(body.id)" + delete_method = "DELETE" +} + +# Azure Test VM & NSG +resource "azurerm_network_security_group" "vm_nsg" { + name = "test-vm-nsg" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + + security_rule { + name = "Allow-STACKIT" + priority = 100 + direction = "Inbound" + access = "Allow" + protocol = "*" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "10.10.0.0/16" + destination_address_prefix = "*" + } +} + +resource "azurerm_network_interface" "vm_nic" { + name = "test-vm-nic" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name + + ip_configuration { + name = "internal" + subnet_id = azurerm_subnet.azure_vm_subnet.id + private_ip_address_allocation = "Dynamic" + } +} + +resource "azurerm_network_interface_security_group_association" "vm_nsg_assoc" { + network_interface_id = azurerm_network_interface.vm_nic.id + network_security_group_id = azurerm_network_security_group.vm_nsg.id +} + +resource "azurerm_linux_virtual_machine" "azure_test_vm" { + name = "azure-vpn-test-vm" + resource_group_name = azurerm_resource_group.rg.name + location = azurerm_resource_group.rg.location + size = "Standard_B1s" + admin_username = "azureuser" + admin_password = "VpnTestPassw0rd!" + disable_password_authentication = false + + network_interface_ids = [ + azurerm_network_interface.vm_nic.id, + ] + + os_disk { + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } + + source_image_reference { + publisher = "Canonical" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" + version = "latest" + } +} + +# Outputs +output "vpn01_public_ip" { + value = module.vpn_sna_01.machine_public_ip + description = "Connect here via SSH to ping Azure" +} + +output "vpn01_private_ip" { + value = module.vpn_sna_01.machine_private_ipv4 +} + +output "azure_test_vm_private_ip" { + value = azurerm_linux_virtual_machine.azure_test_vm.private_ip_address +} + +# Command to run a ping test without SSHing +output "azure_run_command_ping_test" { + value = "az vm run-command invoke --resource-group ${azurerm_resource_group.rg.name} --name ${azurerm_linux_virtual_machine.azure_test_vm.name} --command-id RunShellScript --scripts 'ping -c 4 ${module.vpn_sna_01.machine_private_ipv4}'" + description = "Copy and paste this in your terminal to securely ping from the Azure VM to the STACKIT VM." +} diff --git a/examples/vpn-usecases/stackit-azure/MAINTAINERS.md b/examples/vpn-usecases/stackit-azure/MAINTAINERS.md new file mode 100644 index 0000000..1aaefce --- /dev/null +++ b/examples/vpn-usecases/stackit-azure/MAINTAINERS.md @@ -0,0 +1,9 @@ +# Maintainers + +General maintainers: + +- Mauritz Uphoff (mauritz.uphoff@digits.schwarz) + +This example is actively maintained. The owner is responsible for reviewing and updating dependencies and functionalities on a monthly basis. +For questions, issues, or feature requests, please email general maintainers. +Please include the BP name and version in your request. We will track your request as an issue. diff --git a/examples/vpn-usecases/stackit-azure/README.md b/examples/vpn-usecases/stackit-azure/README.md new file mode 100644 index 0000000..626bac6 --- /dev/null +++ b/examples/vpn-usecases/stackit-azure/README.md @@ -0,0 +1,48 @@ +# STACKIT-to-Azure HA VPN Gateway + +> ⚠️ azurerm_virtual_network_gateway.azure_gateway takes between 30-90mins + +This example demonstrates how to establish a secure, Highly Available (HA) IPsec VPN connection between a STACKIT Network Area (SNA) and Microsoft Azure. + +The connection uses **BGP (Border Gateway Protocol)** via an Azure Virtual Network Gateway (Active-Active mode) to automatically exchange and propagate routes dynamically between the two cloud environments. + +## Architecture + +This Terraform configuration provisions the following resources: + +- **STACKIT:** An SNA, a debug machine, and an HA VPN Gateway (`ASN 64512`). +- **Azure:** A Resource Group, VNet, dedicated `GatewaySubnet`, an Active-Active Virtual Network Gateway (`ASN 64513`), two Local Network Gateways (representing STACKIT), and a private Ubuntu test VM. +- **VPN Connection:** Two redundant IPsec tunnels using dynamically generated PSKs and Link-Local BGP peering (`169.254.x.x/30`). +- **Security:** Azure Network Security Group (NSG) rules configured to allow inbound ICMP/SSH traffic specifically from the STACKIT network range. + +## Prerequisites + +- Configured STACKIT and Azure provider credentials. +- Azure CLI (`az`) installed and authenticated for testing from the Azure side. + +## Outputs + +Once the deployment is complete, Terraform will output the following information to help you verify connectivity: + +- `vpn01_public_ip`: The public IP of the debug machine in STACKIT. +- `vpn01_private_ip`: The private IP of the debug machine in STACKIT. +- `azure_test_vm_private_ip`: The private IP of the test VM in Azure. +- `azure_run_command_ping_test`: A pre-formatted Azure CLI command to test the connection. + +## How to Test the Connection + +You can verify the bi-directional tunnel is fully operational by following these steps: + +### 1. Test from Azure to STACKIT (Zero-Config) + +We utilize the Azure "Run Command" feature to execute a ping test directly inside the private Azure VM without needing SSH access or a Bastion host. + +Copy the command generated by the `azure_run_command_ping_test` output and run it in your terminal: + +```bash +az vm run-command invoke \ + --resource-group rg-vpn-test \ + --name azure-vpn-test-vm \ + --command-id RunShellScript \ + --scripts 'ping -c 4
"10.28.0.0/16"
]