From 796719240aab42955ab93aaa4c61a67763aa3360 Mon Sep 17 00:00:00 2001 From: Tim Reibe Date: Thu, 25 Jun 2026 18:44:47 +0200 Subject: [PATCH 1/3] examples(tf-pg-backend): added terraform pg backend with state lock --- .../00-bootstrap/000-variables.tf | 43 ++++++++++++++ .../00-bootstrap/010-provider.tf | 27 +++++++++ .../00-bootstrap/020-project.tf | 19 +++++++ .../00-bootstrap/030-postgresql_flex.tf | 53 ++++++++++++++++++ .../00-bootstrap/040-output.tf | 13 +++++ .../00-bootstrap/README.md | 23 ++++++++ .../00-bootstrap/terraform.tfvars.example | 31 ++++++++++ .../01-example-project/000-variables.tf | 43 ++++++++++++++ .../01-example-project/010-backend.tf | 3 + .../01-example-project/020-provider.tf | 27 +++++++++ .../01-example-project/030-project.tf | 19 +++++++ .../01-example-project/README.md | 56 +++++++++++++++++++ .../01-example-project/backend.conf.example | 1 + .../scripts/validate_lock.sh | 30 ++++++++++ .../terraform.tfvars.example | 31 ++++++++++ examples/terraform-pg-state-locking/README.md | 8 +++ 16 files changed, 427 insertions(+) create mode 100644 examples/terraform-pg-state-locking/00-bootstrap/000-variables.tf create mode 100644 examples/terraform-pg-state-locking/00-bootstrap/010-provider.tf create mode 100644 examples/terraform-pg-state-locking/00-bootstrap/020-project.tf create mode 100644 examples/terraform-pg-state-locking/00-bootstrap/030-postgresql_flex.tf create mode 100644 examples/terraform-pg-state-locking/00-bootstrap/040-output.tf create mode 100644 examples/terraform-pg-state-locking/00-bootstrap/README.md create mode 100644 examples/terraform-pg-state-locking/00-bootstrap/terraform.tfvars.example create mode 100644 examples/terraform-pg-state-locking/01-example-project/000-variables.tf create mode 100644 examples/terraform-pg-state-locking/01-example-project/010-backend.tf create mode 100644 examples/terraform-pg-state-locking/01-example-project/020-provider.tf create mode 100644 examples/terraform-pg-state-locking/01-example-project/030-project.tf create mode 100644 examples/terraform-pg-state-locking/01-example-project/README.md create mode 100644 examples/terraform-pg-state-locking/01-example-project/backend.conf.example create mode 100755 examples/terraform-pg-state-locking/01-example-project/scripts/validate_lock.sh create mode 100644 examples/terraform-pg-state-locking/01-example-project/terraform.tfvars.example create mode 100644 examples/terraform-pg-state-locking/README.md diff --git a/examples/terraform-pg-state-locking/00-bootstrap/000-variables.tf b/examples/terraform-pg-state-locking/00-bootstrap/000-variables.tf new file mode 100644 index 0000000..95546e5 --- /dev/null +++ b/examples/terraform-pg-state-locking/00-bootstrap/000-variables.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. + +variable "stackit_service_account_key_path" { + description = "Path to the STACKIT service account key file (JSON). Keep this file out of version control." + type = string +} + +variable "stackit_organization_id" { + description = "STACKIT Organization ID (UUID). Found in the portal under Organization > Settings." + type = string +} + +variable "stackit_project_name" { + description = "Display name of the hub project in STACKIT." + type = string +} + +variable "stackit_org_admin" { + description = "Email address of the STACKIT user who will be set as project owner." + type = string +} + +variable "stackit_region" { + description = "STACKIT region (e.g. eu01)." + type = string +} + +variable "default_zone" { + description = "Availability zone within the region (e.g. eu01-1)." + type = string +} diff --git a/examples/terraform-pg-state-locking/00-bootstrap/010-provider.tf b/examples/terraform-pg-state-locking/00-bootstrap/010-provider.tf new file mode 100644 index 0000000..f57f226 --- /dev/null +++ b/examples/terraform-pg-state-locking/00-bootstrap/010-provider.tf @@ -0,0 +1,27 @@ +# 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.99.0" + } + } +} + +provider "stackit" { + default_region = var.stackit_region + service_account_key_path = var.stackit_service_account_key_path +} diff --git a/examples/terraform-pg-state-locking/00-bootstrap/020-project.tf b/examples/terraform-pg-state-locking/00-bootstrap/020-project.tf new file mode 100644 index 0000000..1169d4f --- /dev/null +++ b/examples/terraform-pg-state-locking/00-bootstrap/020-project.tf @@ -0,0 +1,19 @@ +# 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_resourcemanager_project" "this" { + parent_container_id = var.stackit_organization_id + name = var.stackit_project_name + owner_email = var.stackit_org_admin +} diff --git a/examples/terraform-pg-state-locking/00-bootstrap/030-postgresql_flex.tf b/examples/terraform-pg-state-locking/00-bootstrap/030-postgresql_flex.tf new file mode 100644 index 0000000..11e2c85 --- /dev/null +++ b/examples/terraform-pg-state-locking/00-bootstrap/030-postgresql_flex.tf @@ -0,0 +1,53 @@ +# 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. + +# Provision PostgreSQL Flex Database Instance +resource "stackit_postgresflex_instance" "this" { + project_id = stackit_resourcemanager_project.this.project_id + name = "tf-state-instance" + version = "17" + + flavor = { + cpu = 2 + ram = 4 + } + storage = { + class = "premium-perf2-stackit" + size = 10 + } + + replicas = 1 + backup_schedule = "00 00 * * *" + + acl = [ + "0.0.0.0/0" + ] + +} + +# Provision PostgreSQL Flex Database Owner +resource "stackit_postgresflex_user" "db_owner" { + project_id = stackit_resourcemanager_project.this.project_id + instance_id = stackit_postgresflex_instance.this.instance_id + username = "tf_state_user" + roles = ["login", "createdb"] +} + +# Provision PostgreSQL Flex Database +resource "stackit_postgresflex_database" "this" { + project_id = stackit_resourcemanager_project.this.project_id + instance_id = stackit_postgresflex_instance.this.instance_id + owner = stackit_postgresflex_user.db_owner.username + name = "tf-states" +} diff --git a/examples/terraform-pg-state-locking/00-bootstrap/040-output.tf b/examples/terraform-pg-state-locking/00-bootstrap/040-output.tf new file mode 100644 index 0000000..2aa23e6 --- /dev/null +++ b/examples/terraform-pg-state-locking/00-bootstrap/040-output.tf @@ -0,0 +1,13 @@ +locals { + pg_username = stackit_postgresflex_user.db_owner.username + pg_password = stackit_postgresflex_user.db_owner.password + pg_host = stackit_postgresflex_user.db_owner.host + pg_port = stackit_postgresflex_user.db_owner.port + pg_database = stackit_postgresflex_database.this.name +} + +output "pg_connection_uri" { + description = "PostgreSQL Flex User Connection String" + value = "postgres://${local.pg_username}:${local.pg_password}@${local.pg_host}:${local.pg_port}/${local.pg_database}?sslmode=require" + sensitive = true +} diff --git a/examples/terraform-pg-state-locking/00-bootstrap/README.md b/examples/terraform-pg-state-locking/00-bootstrap/README.md new file mode 100644 index 0000000..be7962b --- /dev/null +++ b/examples/terraform-pg-state-locking/00-bootstrap/README.md @@ -0,0 +1,23 @@ +# Phase 0: Bootstrap + +This module provisions the STACKIT PostgreSQL Flex instance, the `terraform_state` database, and the dedicated `tf_state_user`. Its state is kept locally (or in an independent CI/CD backend) to prevent dependency conflicts. + +## Implementation Steps + +1. Initialize Terraform with the default local backend: + + ```sh + terraform init + ``` + +2. Provision the PostgreSQL Flex resources: + + ```sh + terraform apply + ``` + +3. Extract the generated PostgreSQL connection string from the Terraform outputs. This URI is required to configure the remote backend in the next phase. + + ```sh + terraform output -raw pg_connection_uri + ``` diff --git a/examples/terraform-pg-state-locking/00-bootstrap/terraform.tfvars.example b/examples/terraform-pg-state-locking/00-bootstrap/terraform.tfvars.example new file mode 100644 index 0000000..d16ff30 --- /dev/null +++ b/examples/terraform-pg-state-locking/00-bootstrap/terraform.tfvars.example @@ -0,0 +1,31 @@ +# --------------------------------------------------------------------------- +# terraform.tfvars.example +# +# Copy this file into a project directory (e.g. 00-bootcamp/terraform.tfvars) +# and fill in your values. Do NOT commit terraform.tfvars to version control. +# +# Alternatively, export variables as environment variables: +# export TF_VAR_stackit_organization_id="" +# --------------------------------------------------------------------------- + +# --- STACKIT Identity -------------------------------------------------------- + +# Your STACKIT Organization ID. +# Portal: Organization > Settings > Organization ID +stackit_organization_id = "" + +## Name of the bootstrapping project +stackit_project_name = "01-example-project" + +# Email address of the STACKIT user set as project owner. +stackit_org_admin = " Service Accounts > Keys > Create key +stackit_service_account_key_path = "./keys/service-account.json" + +# --- Region ------------------------------------------------------------------ +stackit_region = "eu01" +default_zone = "eu01-1" diff --git a/examples/terraform-pg-state-locking/01-example-project/000-variables.tf b/examples/terraform-pg-state-locking/01-example-project/000-variables.tf new file mode 100644 index 0000000..95546e5 --- /dev/null +++ b/examples/terraform-pg-state-locking/01-example-project/000-variables.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. + +variable "stackit_service_account_key_path" { + description = "Path to the STACKIT service account key file (JSON). Keep this file out of version control." + type = string +} + +variable "stackit_organization_id" { + description = "STACKIT Organization ID (UUID). Found in the portal under Organization > Settings." + type = string +} + +variable "stackit_project_name" { + description = "Display name of the hub project in STACKIT." + type = string +} + +variable "stackit_org_admin" { + description = "Email address of the STACKIT user who will be set as project owner." + type = string +} + +variable "stackit_region" { + description = "STACKIT region (e.g. eu01)." + type = string +} + +variable "default_zone" { + description = "Availability zone within the region (e.g. eu01-1)." + type = string +} diff --git a/examples/terraform-pg-state-locking/01-example-project/010-backend.tf b/examples/terraform-pg-state-locking/01-example-project/010-backend.tf new file mode 100644 index 0000000..637aeee --- /dev/null +++ b/examples/terraform-pg-state-locking/01-example-project/010-backend.tf @@ -0,0 +1,3 @@ +terraform { + backend "pg" {} +} diff --git a/examples/terraform-pg-state-locking/01-example-project/020-provider.tf b/examples/terraform-pg-state-locking/01-example-project/020-provider.tf new file mode 100644 index 0000000..f57f226 --- /dev/null +++ b/examples/terraform-pg-state-locking/01-example-project/020-provider.tf @@ -0,0 +1,27 @@ +# 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.99.0" + } + } +} + +provider "stackit" { + default_region = var.stackit_region + service_account_key_path = var.stackit_service_account_key_path +} diff --git a/examples/terraform-pg-state-locking/01-example-project/030-project.tf b/examples/terraform-pg-state-locking/01-example-project/030-project.tf new file mode 100644 index 0000000..1169d4f --- /dev/null +++ b/examples/terraform-pg-state-locking/01-example-project/030-project.tf @@ -0,0 +1,19 @@ +# 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_resourcemanager_project" "this" { + parent_container_id = var.stackit_organization_id + name = var.stackit_project_name + owner_email = var.stackit_org_admin +} diff --git a/examples/terraform-pg-state-locking/01-example-project/README.md b/examples/terraform-pg-state-locking/01-example-project/README.md new file mode 100644 index 0000000..80fca7b --- /dev/null +++ b/examples/terraform-pg-state-locking/01-example-project/README.md @@ -0,0 +1,56 @@ +# Phase 1: Example Infrastructure + +This module contains the core infrastructure configuration. It uses the `pg` backend to store state and enforce state locks via the STACKIT PostgreSQL Flex database provisioned in Phase 0. + +## Implementation Steps + +1. Create a `backend.conf` file in this directory and define the connection string using the credentials generated by the bootstrap module: + + ```ini + conn_str = "postgres://tf_state_user:@:5432/terraform_state?sslmode=require" + ``` + +2. Initialize Terraform and bind it to the remote PostgreSQL backend + + ```sh + terraform init -backend-config=backend.conf + ``` + +3. Provision the infrastructure or run the lock validation script: + + ```sh + chmod +x ./scripts/validate_lock.sh + ./scripts/validate_lock.sh + ``` + +## Log Output + +```sh +➜ 01-example-project ~ ./scripts/test-state-lock.sh +[INFO] Initiating background 'terraform apply' to acquire the state lock... +[INFO] Attempting concurrent 'terraform plan'... +[INFO] ------------------------------------------------------------------ +╷ +│ Error: Error acquiring the state lock +│ +│ Error message: Already locked for workspace creation: default +│ Lock Info: +│ ID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXXXX +│ Path: +│ Operation: OperationTypePlan +│ Who: XXXX +│ Version: 1.14.9 +│ Created: 2026-06-25 16:21:59.636986 +0000 UTC +│ Info: +│ +│ +│ Terraform acquires a state lock to protect the state from being written +│ by multiple users at the same time. Please resolve the issue above and try +│ again. For most commands, you can disable locking with the "-lock=false" +│ flag, but this is not recommended. +╵ +[INFO] ------------------------------------------------------------------ +[SUCCESS] Concurrent operation rejected. State locking is active and functional. +[INFO] Waiting for the background 'terraform apply' process to terminate... +[INFO] Evaluation complete. Cleaning up temporary logs... +``` diff --git a/examples/terraform-pg-state-locking/01-example-project/backend.conf.example b/examples/terraform-pg-state-locking/01-example-project/backend.conf.example new file mode 100644 index 0000000..a44a0ab --- /dev/null +++ b/examples/terraform-pg-state-locking/01-example-project/backend.conf.example @@ -0,0 +1 @@ +conn_str="" diff --git a/examples/terraform-pg-state-locking/01-example-project/scripts/validate_lock.sh b/examples/terraform-pg-state-locking/01-example-project/scripts/validate_lock.sh new file mode 100755 index 0000000..8f7e557 --- /dev/null +++ b/examples/terraform-pg-state-locking/01-example-project/scripts/validate_lock.sh @@ -0,0 +1,30 @@ +#!/bin/bash +set -u + +echo "[INFO] Initiating background 'terraform apply' to acquire the state lock..." +# Redirecting output to avoid console clutter during the concurrent test +terraform apply -auto-approve > apply_bg.log 2>&1 & +APPLY_PID=$! + +echo "[INFO] Attempting concurrent 'terraform plan'..." +echo "[INFO] ------------------------------------------------------------------" + +# Disable exit-on-error to capture the expected failure code +set +e +terraform plan +PLAN_EXIT_CODE=$? +set -e + +echo "[INFO] ------------------------------------------------------------------" + +if [ $PLAN_EXIT_CODE -ne 0 ]; then + echo "[SUCCESS] Concurrent operation rejected. State locking is active and functional." +else + echo "[ERROR] Concurrent operation succeeded. State locking failed or is misconfigured." +fi + +echo "[INFO] Waiting for the background 'terraform apply' process to terminate..." +wait $APPLY_PID + +echo "[INFO] Evaluation complete. Cleaning up temporary logs..." +rm -f apply_bg.log diff --git a/examples/terraform-pg-state-locking/01-example-project/terraform.tfvars.example b/examples/terraform-pg-state-locking/01-example-project/terraform.tfvars.example new file mode 100644 index 0000000..d16ff30 --- /dev/null +++ b/examples/terraform-pg-state-locking/01-example-project/terraform.tfvars.example @@ -0,0 +1,31 @@ +# --------------------------------------------------------------------------- +# terraform.tfvars.example +# +# Copy this file into a project directory (e.g. 00-bootcamp/terraform.tfvars) +# and fill in your values. Do NOT commit terraform.tfvars to version control. +# +# Alternatively, export variables as environment variables: +# export TF_VAR_stackit_organization_id="" +# --------------------------------------------------------------------------- + +# --- STACKIT Identity -------------------------------------------------------- + +# Your STACKIT Organization ID. +# Portal: Organization > Settings > Organization ID +stackit_organization_id = "" + +## Name of the bootstrapping project +stackit_project_name = "01-example-project" + +# Email address of the STACKIT user set as project owner. +stackit_org_admin = " Service Accounts > Keys > Create key +stackit_service_account_key_path = "./keys/service-account.json" + +# --- Region ------------------------------------------------------------------ +stackit_region = "eu01" +default_zone = "eu01-1" diff --git a/examples/terraform-pg-state-locking/README.md b/examples/terraform-pg-state-locking/README.md new file mode 100644 index 0000000..dc91fbe --- /dev/null +++ b/examples/terraform-pg-state-locking/README.md @@ -0,0 +1,8 @@ +# STACKIT Terraform PostgreSQL Backend with State Locking + +This repository demonstrates how to configure STACKIT PostgreSQL Flex as a Terraform backend to enable remote state storage and native state locking. + +To resolve the circular dependency of provisioning a state backend using Terraform, the deployment is split into two isolated stages: + +1. **`00-bootstrap/`**: Provisions the backend infrastructure (PostgreSQL Flex instance, database and service user). +2. **`01-example/`**: Represents the primary infrastructure, utilizing the provisioned PostgreSQL database as its remote backend. -- 2.49.1 From 34407d936bb6d1dd9ac025f15d53b22ed0272c36 Mon Sep 17 00:00:00 2001 From: Tim Reibe Date: Fri, 26 Jun 2026 10:50:24 +0200 Subject: [PATCH 2/3] added MAINTAINERS.md --- .../00-bootstrap/README.md | 18 +++++------ .../01-example-project/README.md | 32 +++++++++---------- .../terraform-pg-state-locking/MAINTAINERS.md | 9 ++++++ 3 files changed, 34 insertions(+), 25 deletions(-) create mode 100644 examples/terraform-pg-state-locking/MAINTAINERS.md diff --git a/examples/terraform-pg-state-locking/00-bootstrap/README.md b/examples/terraform-pg-state-locking/00-bootstrap/README.md index be7962b..b8398d5 100644 --- a/examples/terraform-pg-state-locking/00-bootstrap/README.md +++ b/examples/terraform-pg-state-locking/00-bootstrap/README.md @@ -6,18 +6,18 @@ This module provisions the STACKIT PostgreSQL Flex instance, the `terraform_stat 1. Initialize Terraform with the default local backend: - ```sh - terraform init - ``` + ```sh + terraform init + ``` 2. Provision the PostgreSQL Flex resources: - ```sh - terraform apply - ``` + ```sh + terraform apply + ``` 3. Extract the generated PostgreSQL connection string from the Terraform outputs. This URI is required to configure the remote backend in the next phase. - ```sh - terraform output -raw pg_connection_uri - ``` + ```sh + terraform output -raw pg_connection_uri + ``` diff --git a/examples/terraform-pg-state-locking/01-example-project/README.md b/examples/terraform-pg-state-locking/01-example-project/README.md index 80fca7b..f1f211d 100644 --- a/examples/terraform-pg-state-locking/01-example-project/README.md +++ b/examples/terraform-pg-state-locking/01-example-project/README.md @@ -6,44 +6,44 @@ This module contains the core infrastructure configuration. It uses the `pg` bac 1. Create a `backend.conf` file in this directory and define the connection string using the credentials generated by the bootstrap module: - ```ini - conn_str = "postgres://tf_state_user:@:5432/terraform_state?sslmode=require" - ``` + ```ini + conn_str = "postgres://tf_state_user:@:5432/terraform_state?sslmode=require" + ``` 2. Initialize Terraform and bind it to the remote PostgreSQL backend - ```sh - terraform init -backend-config=backend.conf - ``` + ```sh + terraform init -backend-config=backend.conf + ``` 3. Provision the infrastructure or run the lock validation script: - ```sh - chmod +x ./scripts/validate_lock.sh - ./scripts/validate_lock.sh - ``` + ```sh + chmod +x ./scripts/validate_lock.sh + ./scripts/validate_lock.sh + ``` ## Log Output ```sh -➜ 01-example-project ~ ./scripts/test-state-lock.sh +➜ 01-example-project ~ ./scripts/test-state-lock.sh [INFO] Initiating background 'terraform apply' to acquire the state lock... [INFO] Attempting concurrent 'terraform plan'... [INFO] ------------------------------------------------------------------ ╷ │ Error: Error acquiring the state lock -│ +│ │ Error message: Already locked for workspace creation: default │ Lock Info: │ ID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXXXXX -│ Path: +│ Path: │ Operation: OperationTypePlan │ Who: XXXX │ Version: 1.14.9 │ Created: 2026-06-25 16:21:59.636986 +0000 UTC -│ Info: -│ -│ +│ Info: +│ +│ │ Terraform acquires a state lock to protect the state from being written │ by multiple users at the same time. Please resolve the issue above and try │ again. For most commands, you can disable locking with the "-lock=false" diff --git a/examples/terraform-pg-state-locking/MAINTAINERS.md b/examples/terraform-pg-state-locking/MAINTAINERS.md new file mode 100644 index 0000000..f852b06 --- /dev/null +++ b/examples/terraform-pg-state-locking/MAINTAINERS.md @@ -0,0 +1,9 @@ +# Maintainers + +General maintainers: + +- Tim Reibe () + +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. -- 2.49.1 From 11e39b5950a0d0e8db81bb544ed305003637ce52 Mon Sep 17 00:00:00 2001 From: Tim Reibe Date: Fri, 26 Jun 2026 11:11:39 +0200 Subject: [PATCH 3/3] added license header and .terraform.lock.hcl files --- .../00-bootstrap/.terraform.lock.hcl | 24 +++++++++++++++++++ .../00-bootstrap/040-output.tf | 14 +++++++++++ .../01-example-project/.terraform.lock.hcl | 24 +++++++++++++++++++ .../01-example-project/010-backend.tf | 14 +++++++++++ .../scripts/validate_lock.sh | 14 +++++++++++ 5 files changed, 90 insertions(+) create mode 100644 examples/terraform-pg-state-locking/00-bootstrap/.terraform.lock.hcl create mode 100644 examples/terraform-pg-state-locking/01-example-project/.terraform.lock.hcl diff --git a/examples/terraform-pg-state-locking/00-bootstrap/.terraform.lock.hcl b/examples/terraform-pg-state-locking/00-bootstrap/.terraform.lock.hcl new file mode 100644 index 0000000..ac34bd3 --- /dev/null +++ b/examples/terraform-pg-state-locking/00-bootstrap/.terraform.lock.hcl @@ -0,0 +1,24 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/stackitcloud/stackit" { + version = "0.99.0" + constraints = ">= 0.99.0" + hashes = [ + "h1:a9z0j1z/8GmGjz+VygIhgyBbMqxx7jlXGqCvWBDD1NY=", + "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", + "zh:396c0392b9ef5ec7f8613c29a64e183545cc16dda0ceb876393fc003dba71c73", + "zh:40d86a1fb1c9ed4579583acb8ecc219edca44f9ee5221bfdcbc1bee2ce6654e7", + "zh:4ccbbecc3575737d87195ad13448d06071be9925760a2da5b7e5e8b91517f876", + "zh:506d786647c4566a82487fc3ffe0792f37a63ec8d6b54821aa3c7485e5ed6760", + "zh:848f638c500f1928f8593ae189472add1a0871c1e056d7df06871652ddee3409", + "zh:9ed739aec2c60cdfae3a33e4f349fa630fd0fd0ab50fcec5745774d42a6d6e70", + "zh:c0ac883dd73bd886e419d912c28ec29bb90a611b023cf4ae1b0534945cce1694", + "zh:df28663578694b25453b9d0a1cd7633a0f7fb1c113870cd3c133e9dc05d35946", + "zh:eaacb4a4512f41d44e46f82f042a19ab96c9d90d470890e2fd82c6cafb33bf0e", + "zh:ef9dd9b10571804f3a4dd6062405d0e473df270d75f05f897901c54d7d6c3d9d", + "zh:f40add9cd4fd4a7cda53f4a418c5f47a220b5ba5c4fc2377f60b1e16368f87d9", + "zh:f65deb30c1e3e8018a888d1aed56e895ea1e26b880f22a5772771e9836c9b5a4", + "zh:f8d14feddfd9d785d3ee6469937234a631998758ea5e8c16ecf61cdb94b07564", + ] +} diff --git a/examples/terraform-pg-state-locking/00-bootstrap/040-output.tf b/examples/terraform-pg-state-locking/00-bootstrap/040-output.tf index 2aa23e6..f345841 100644 --- a/examples/terraform-pg-state-locking/00-bootstrap/040-output.tf +++ b/examples/terraform-pg-state-locking/00-bootstrap/040-output.tf @@ -1,3 +1,17 @@ +# 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 { pg_username = stackit_postgresflex_user.db_owner.username pg_password = stackit_postgresflex_user.db_owner.password diff --git a/examples/terraform-pg-state-locking/01-example-project/.terraform.lock.hcl b/examples/terraform-pg-state-locking/01-example-project/.terraform.lock.hcl new file mode 100644 index 0000000..ac34bd3 --- /dev/null +++ b/examples/terraform-pg-state-locking/01-example-project/.terraform.lock.hcl @@ -0,0 +1,24 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/stackitcloud/stackit" { + version = "0.99.0" + constraints = ">= 0.99.0" + hashes = [ + "h1:a9z0j1z/8GmGjz+VygIhgyBbMqxx7jlXGqCvWBDD1NY=", + "zh:0dde99e7b343fa01f8eefc378171fb8621bedb20f59157d6cc8e3d46c738105f", + "zh:396c0392b9ef5ec7f8613c29a64e183545cc16dda0ceb876393fc003dba71c73", + "zh:40d86a1fb1c9ed4579583acb8ecc219edca44f9ee5221bfdcbc1bee2ce6654e7", + "zh:4ccbbecc3575737d87195ad13448d06071be9925760a2da5b7e5e8b91517f876", + "zh:506d786647c4566a82487fc3ffe0792f37a63ec8d6b54821aa3c7485e5ed6760", + "zh:848f638c500f1928f8593ae189472add1a0871c1e056d7df06871652ddee3409", + "zh:9ed739aec2c60cdfae3a33e4f349fa630fd0fd0ab50fcec5745774d42a6d6e70", + "zh:c0ac883dd73bd886e419d912c28ec29bb90a611b023cf4ae1b0534945cce1694", + "zh:df28663578694b25453b9d0a1cd7633a0f7fb1c113870cd3c133e9dc05d35946", + "zh:eaacb4a4512f41d44e46f82f042a19ab96c9d90d470890e2fd82c6cafb33bf0e", + "zh:ef9dd9b10571804f3a4dd6062405d0e473df270d75f05f897901c54d7d6c3d9d", + "zh:f40add9cd4fd4a7cda53f4a418c5f47a220b5ba5c4fc2377f60b1e16368f87d9", + "zh:f65deb30c1e3e8018a888d1aed56e895ea1e26b880f22a5772771e9836c9b5a4", + "zh:f8d14feddfd9d785d3ee6469937234a631998758ea5e8c16ecf61cdb94b07564", + ] +} diff --git a/examples/terraform-pg-state-locking/01-example-project/010-backend.tf b/examples/terraform-pg-state-locking/01-example-project/010-backend.tf index 637aeee..3ea9fdf 100644 --- a/examples/terraform-pg-state-locking/01-example-project/010-backend.tf +++ b/examples/terraform-pg-state-locking/01-example-project/010-backend.tf @@ -1,3 +1,17 @@ +# 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 { backend "pg" {} } diff --git a/examples/terraform-pg-state-locking/01-example-project/scripts/validate_lock.sh b/examples/terraform-pg-state-locking/01-example-project/scripts/validate_lock.sh index 8f7e557..d5ec204 100755 --- a/examples/terraform-pg-state-locking/01-example-project/scripts/validate_lock.sh +++ b/examples/terraform-pg-state-locking/01-example-project/scripts/validate_lock.sh @@ -1,4 +1,18 @@ #!/bin/bash +# 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. + set -u echo "[INFO] Initiating background 'terraform apply' to acquire the state lock..." -- 2.49.1