diff --git a/.gitignore b/.gitignore
index ff2c4e2..75f01ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,4 +36,13 @@ override.tf.json
.terraformrc
terraform.rc
+# Ignore typical plan output files
+*.tfplan
+*.out
+*.plan
+
+.DS_Store
+
*.env
+
+playground/**
diff --git a/.wordlist.txt b/.wordlist.txt
index 42dd981..4060549 100644
--- a/.wordlist.txt
+++ b/.wordlist.txt
@@ -1,4 +1,5 @@
-APIs
+API
+api
autocompletion
APIs
backend
@@ -6,18 +7,26 @@ Backend
breakpoint
BTP
btp
+carte
CLA
CLI
CLIs
+cloudfoundry
+Cloudfoundry
CodeQL
config
Copilot
+costcenter
+Costcenter
customizations
DCO
dependabot
+Dev
+dev
devcontainer
devcontainers
dir
+EMEA
faq
Github
github
@@ -32,8 +41,11 @@ JSON
js
JS
jq
+Kyma
macOS
md
+namings
+Namings
NextSteps
OAuth
OpenSSF
@@ -70,6 +82,12 @@ TOML
toolchain
UIs
UI
+Unmanaged
+unmanaged
+URL
+url
+uuid
+UUID
VS
workspace
workspaces
diff --git a/assets/base-directory-output.png b/assets/base-directory-output.png
new file mode 100644
index 0000000..d366016
Binary files /dev/null and b/assets/base-directory-output.png differ
diff --git a/sample-setups/README.md b/sample-setups/README.md
new file mode 100644
index 0000000..186b3dc
--- /dev/null
+++ b/sample-setups/README.md
@@ -0,0 +1,30 @@
+# Terraform Samples for SAP BTP Administrator's Guide
+
+## Paradigms
+
+We follow the paradigms of a simple and clear Terraform configuration as laid out in the [Simple, Clear, Maintainable](https://rosesecurity.dev/blog/2024/11/24/terraform-proverbs) blog post of the [Development Log](https://rosesecurity.dev/) especially:
+
+- Clear is better than clever.
+- Modules should be reusable, not rigid.
+- Outputs are for sharing.
+- Labels are free; use them liberally.
+- Descriptions are for users.
+- Use positive variable names to avoid double negatives.
+- Name with underscores, not dashes.
+- Using locals makes code descriptive and maintainable.
+
+## Naming Conventions and Tagging
+
+Ensuring naming conventions is one import aspect when provisioning and managing your SAP BTP account. We will align our samples in accordance to the [Naming Conventions for SAP BTP Accounts](https://help.sap.com/docs/btp/btp-admin-guide/naming-conventions-for-sap-btp-accounts).
+
+To ensure consistent naming of your resources, we encapsulate the guidelines in dedicated module. Besides the naming we will also include the labels that can be attached to some resources on SAP BTP.
+
+We have created one module for the level of the [directory](./modules/sap-btp-naming-conventions-directory/README.md) and one for the level of the [subaccount](./modules/sap-btp-naming-conventions-subaccount/README.md).
+
+## Setup of Directories
+
+The setup of directories as a structuring element for the subaccounts is configured in the folder `basic-setup/directory-setup`. The Details about the setup are described in the [README.md](./basic-setup/directory-setup/README.md) file.
+
+## Setup of Subaccounts
+
+The setup of subaccounts is configured in the folder `basic-setup/subaccount-setup`. The Details about the setup are described in the [README.md](./basic-setup/subaccount-setup/README.md) file.
diff --git a/sample-setups/basic-setup/directory-setup/.terraform.lock.hcl b/sample-setups/basic-setup/directory-setup/.terraform.lock.hcl
new file mode 100644
index 0000000..a41edc8
--- /dev/null
+++ b/sample-setups/basic-setup/directory-setup/.terraform.lock.hcl
@@ -0,0 +1,25 @@
+# This file is maintained automatically by "terraform init".
+# Manual edits may be lost in future updates.
+
+provider "registry.terraform.io/sap/btp" {
+ version = "1.11.0"
+ constraints = ">= 1.11.0, ~> 1.11.0"
+ hashes = [
+ "h1:q9XDheshVlSVbcWKmAlOjF+EGTxvpgS+CyMOyPzh3uw=",
+ "zh:16647cac2e5062c4ac9db89d622b1de3375e57372841f65f3e6997a26a2f283d",
+ "zh:548d023762dbd3c2830a151f0beadf58401a70368299625f4c90100997348aed",
+ "zh:55aba6fba636e2d6524f4b180fb1ff0df6328dd3812682726a0b9972c921dbdf",
+ "zh:624fb982f4cfb2c26b1448e6270b6ad891592e4e52a00718781579fb5a079adb",
+ "zh:6319aa5b8c60c3916eff4142ecf6f297a8baf1bc903c98a29b6c248a3984f488",
+ "zh:7979a475dd06d12255269fe6ec004d1c460bb64869a9d814bec58bec88b65147",
+ "zh:967b5d6b71053e19dbb017319b8b8bd84d8c7f7cfba6fbb4b23243ce860c370e",
+ "zh:97b02bc0cd9d74bbf4b89b4f8cd9508f0eec7b772b88704f70b696c425a5165e",
+ "zh:a398f2697184f49cb5e32a6c7b3f586a8a723a2d533a4cc13e11d8739fabf6b2",
+ "zh:b9e0a0a986cf8a790c10d469f61c81e9cfc41f4a188f060fb1c5a7612101a4da",
+ "zh:d03b1276c08f7b9d5da9d89505d1a71c0f806142ef336f26abd85a144a68b895",
+ "zh:dd6e32cf30f53707fec2acb1e5c69c044a76349706785bfcdee8fbaa6bb053c6",
+ "zh:e7afd57c00ba45a6be5005620e44db08eec2e6adb97b0af1ffb57963767f8229",
+ "zh:f29dc297897b96bf39f4b6737e6b9e2b8339c3ddc362fc5466ce901d84ef8cb9",
+ "zh:f6057496ac45093be445ed8423dc9dfcdbb21e5cc6d6348dbe3a8d5641882f3f",
+ ]
+}
diff --git a/sample-setups/basic-setup/directory-setup/README.md b/sample-setups/basic-setup/directory-setup/README.md
new file mode 100644
index 0000000..1d7d952
--- /dev/null
+++ b/sample-setups/basic-setup/directory-setup/README.md
@@ -0,0 +1,31 @@
+# Sample Setup for a Basic Directory Structure
+
+## Assumptions
+
+- We assume that we use the directories as structuring element for the subaccounts i.e., in an unmanaged fashion.
+- We assume that we do the directory setup in one run for all involved departments.
+
+## Design Decisions
+
+We decouple the directory creation i.e., the setup of the basic structure from the creation of the operational units namely the subaccounts inside of the directories. The changes on directory level are probably a rare scenario compared to changes in the subaccounts additionally depending on their stage. We want to avoid side effects as well as lengthy state refreshes and keep the state of the directories separate.
+
+## Directory Setup
+
+The creation of the directories is steered by a map of objects that define the business data relevant for a directory namely:
+
+- business_unit (`string`): The business unit that owns the directory e.g., HR, IT, Finance
+- costcenter (`string`): Cost center of the business unit
+- directory_contacts (`list(string)`): List of email addresses representing the directory contacts
+- region (`string`): The geographical region of the directory e.g., EMEA
+
+This is input data is reflected by the variables defined in the [variables.tf](./variables.tf) file
+
+The directories are provisioned via the [main.tf](./main.tf) file which delegates to the module [base-directory-setup](../../modules/base-directory-setup/README.md). This module combines the corresponding module containing the naming and labeling conventions for a directory and calls the Terraform resource [btp_directory](https://registry.terraform.io/providers/SAP/btp/latest/docs/resources/directory).
+
+After provisioning the output summarizes the executed setup as given by the [outputs.tf](./outputs.tf) file. Here is an example how the output could look like:
+
+
+
+## SAP BTP Administrator's Guide - References
+
+- [Naming and Directory Templates](https://help.sap.com/docs/btp/btp-admin-guide/naming-directory-templates)
diff --git a/sample-setups/basic-setup/directory-setup/main.tf b/sample-setups/basic-setup/directory-setup/main.tf
new file mode 100644
index 0000000..7b4ba45
--- /dev/null
+++ b/sample-setups/basic-setup/directory-setup/main.tf
@@ -0,0 +1,10 @@
+module "directory" {
+ source = "../../modules/base-directory-setup"
+
+ for_each = var.directory_inputs
+
+ business_unit = each.value.business_unit
+ costcenter = each.value.costcenter
+ directory_contacts = each.value.directory_contacts
+ region = each.value.region
+}
diff --git a/sample-setups/basic-setup/directory-setup/outputs.tf b/sample-setups/basic-setup/directory-setup/outputs.tf
new file mode 100644
index 0000000..5dd17ad
--- /dev/null
+++ b/sample-setups/basic-setup/directory-setup/outputs.tf
@@ -0,0 +1,11 @@
+output "directories" {
+ value = {
+ for k, v in module.directory : k => {
+ id = v.directory_id
+ name = v.directory_name
+ business_unit = v.business_unit
+ costcenter = v.costcenter
+ region = v.region
+ }
+ }
+}
diff --git a/sample-setups/basic-setup/directory-setup/provider.tf b/sample-setups/basic-setup/directory-setup/provider.tf
new file mode 100644
index 0000000..52f55ff
--- /dev/null
+++ b/sample-setups/basic-setup/directory-setup/provider.tf
@@ -0,0 +1,13 @@
+terraform {
+ required_providers {
+ btp = {
+ source = "SAP/btp"
+ version = "~>1.11.0"
+ }
+ }
+}
+
+# Configure the BTP Provider
+provider "btp" {
+ globalaccount = var.globalaccount
+}
diff --git a/sample-setups/basic-setup/directory-setup/variables.tf b/sample-setups/basic-setup/directory-setup/variables.tf
new file mode 100644
index 0000000..da7bafb
--- /dev/null
+++ b/sample-setups/basic-setup/directory-setup/variables.tf
@@ -0,0 +1,22 @@
+variable "globalaccount" {
+ type = string
+ description = "The subdomain of the global account on SAP BTP"
+}
+
+variable "directory_inputs" {
+ type = map(object({
+ business_unit = string
+ costcenter = string
+ directory_contacts = list(string)
+ region = string
+ }))
+ description = <<-EOT
+ The inputs for the directory module.
+ - `business_unit`: Business unit of the project e.g., HR, IT or Sales
+ - `costcenter`: Cost center to be used for subaccounts
+ - `directory_contacts`: Contact persons to be used for directories, added as label
+ - `region`: The geographical region for a directory. The parameter is optional
+ If you set it the possible values are: `EMEA`, `APAC`, `AMER`.
+ Default value: `null`.
+ EOT
+}
diff --git a/sample-setups/basic-setup/subaccount-setup/.terraform.lock.hcl b/sample-setups/basic-setup/subaccount-setup/.terraform.lock.hcl
new file mode 100644
index 0000000..6451737
--- /dev/null
+++ b/sample-setups/basic-setup/subaccount-setup/.terraform.lock.hcl
@@ -0,0 +1,63 @@
+# This file is maintained automatically by "terraform init".
+# Manual edits may be lost in future updates.
+
+provider "registry.terraform.io/hashicorp/null" {
+ version = "3.2.3"
+ hashes = [
+ "h1:I0Um8UkrMUb81Fxq/dxbr3HLP2cecTH2WMJiwKSrwQY=",
+ "zh:22d062e5278d872fe7aed834f5577ba0a5afe34a3bdac2b81f828d8d3e6706d2",
+ "zh:23dead00493ad863729495dc212fd6c29b8293e707b055ce5ba21ee453ce552d",
+ "zh:28299accf21763ca1ca144d8f660688d7c2ad0b105b7202554ca60b02a3856d3",
+ "zh:55c9e8a9ac25a7652df8c51a8a9a422bd67d784061b1de2dc9fe6c3cb4e77f2f",
+ "zh:756586535d11698a216291c06b9ed8a5cc6a4ec43eee1ee09ecd5c6a9e297ac1",
+ "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
+ "zh:9d5eea62fdb587eeb96a8c4d782459f4e6b73baeece4d04b4a40e44faaee9301",
+ "zh:a6355f596a3fb8fc85c2fb054ab14e722991533f87f928e7169a486462c74670",
+ "zh:b5a65a789cff4ada58a5baffc76cb9767dc26ec6b45c00d2ec8b1b027f6db4ed",
+ "zh:db5ab669cf11d0e9f81dc380a6fdfcac437aea3d69109c7aef1a5426639d2d65",
+ "zh:de655d251c470197bcbb5ac45d289595295acb8f829f6c781d4a75c8c8b7c7dd",
+ "zh:f5c68199f2e6076bce92a12230434782bf768103a427e9bb9abee99b116af7b5",
+ ]
+}
+
+provider "registry.terraform.io/hashicorp/random" {
+ version = "3.7.1"
+ hashes = [
+ "h1:t152MY0tQH4a8fLzTtEWx70ITd3azVOrFDn/pQblbto=",
+ "zh:3193b89b43bf5805493e290374cdda5132578de6535f8009547c8b5d7a351585",
+ "zh:3218320de4be943e5812ed3de995946056db86eb8d03aa3f074e0c7316599bef",
+ "zh:419861805a37fa443e7d63b69fb3279926ccf98a79d256c422d5d82f0f387d1d",
+ "zh:4df9bd9d839b8fc11a3b8098a604b9b46e2235eb65ef15f4432bde0e175f9ca6",
+ "zh:5814be3f9c9cc39d2955d6f083bae793050d75c572e70ca11ccceb5517ced6b1",
+ "zh:63c6548a06de1231c8ee5570e42ca09c4b3db336578ded39b938f2156f06dd2e",
+ "zh:697e434c6bdee0502cc3deb098263b8dcd63948e8a96d61722811628dce2eba1",
+ "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
+ "zh:a0b8e44927e6327852bbfdc9d408d802569367f1e22a95bcdd7181b1c3b07601",
+ "zh:b7d3af018683ef22794eea9c218bc72d7c35a2b3ede9233b69653b3c782ee436",
+ "zh:d63b911d618a6fe446c65bfc21e793a7663e934b2fef833d42d3ccd38dd8d68d",
+ "zh:fa985cd0b11e6d651f47cff3055f0a9fd085ec190b6dbe99bf5448174434cdea",
+ ]
+}
+
+provider "registry.terraform.io/sap/btp" {
+ version = "1.11.0"
+ constraints = "~> 1.11.0"
+ hashes = [
+ "h1:q9XDheshVlSVbcWKmAlOjF+EGTxvpgS+CyMOyPzh3uw=",
+ "zh:16647cac2e5062c4ac9db89d622b1de3375e57372841f65f3e6997a26a2f283d",
+ "zh:548d023762dbd3c2830a151f0beadf58401a70368299625f4c90100997348aed",
+ "zh:55aba6fba636e2d6524f4b180fb1ff0df6328dd3812682726a0b9972c921dbdf",
+ "zh:624fb982f4cfb2c26b1448e6270b6ad891592e4e52a00718781579fb5a079adb",
+ "zh:6319aa5b8c60c3916eff4142ecf6f297a8baf1bc903c98a29b6c248a3984f488",
+ "zh:7979a475dd06d12255269fe6ec004d1c460bb64869a9d814bec58bec88b65147",
+ "zh:967b5d6b71053e19dbb017319b8b8bd84d8c7f7cfba6fbb4b23243ce860c370e",
+ "zh:97b02bc0cd9d74bbf4b89b4f8cd9508f0eec7b772b88704f70b696c425a5165e",
+ "zh:a398f2697184f49cb5e32a6c7b3f586a8a723a2d533a4cc13e11d8739fabf6b2",
+ "zh:b9e0a0a986cf8a790c10d469f61c81e9cfc41f4a188f060fb1c5a7612101a4da",
+ "zh:d03b1276c08f7b9d5da9d89505d1a71c0f806142ef336f26abd85a144a68b895",
+ "zh:dd6e32cf30f53707fec2acb1e5c69c044a76349706785bfcdee8fbaa6bb053c6",
+ "zh:e7afd57c00ba45a6be5005620e44db08eec2e6adb97b0af1ffb57963767f8229",
+ "zh:f29dc297897b96bf39f4b6737e6b9e2b8339c3ddc362fc5466ce901d84ef8cb9",
+ "zh:f6057496ac45093be445ed8423dc9dfcdbb21e5cc6d6348dbe3a8d5641882f3f",
+ ]
+}
diff --git a/sample-setups/basic-setup/subaccount-setup/README.md b/sample-setups/basic-setup/subaccount-setup/README.md
new file mode 100644
index 0000000..59ee6c9
--- /dev/null
+++ b/sample-setups/basic-setup/subaccount-setup/README.md
@@ -0,0 +1,60 @@
+# Setup of a Subaccount
+
+## Assumptions
+
+- We assume a basic setup of a subaccount is executed by the platform team/ SAP BTP administrator team
+- We assume that the responsibility of the platform team is restricted to a basic setup of a subaccount leaving out app subscriptions and service instance creation.
+
+## Design Decisions
+
+To keep the Terraform state files clearly separated the setup is done per subaccount i.e. per stage.
+
+## Subaccount Setup
+
+The setup of the subaccount comprises:
+
+- The setup of a subaccount in accordance to the naming conventions and labeling strategy of the company
+- The trust configuration to a custom IdP is configured by default.
+- Default entitlements are added depending on the stage. In addition the requesting team can add additional project specific entitlements ("à la carte entitlements")
+- Optionally a Cloud Foundry Environment is created
+
+### Naming Conventions and Labels
+
+The naming conventions and labels are centralized in the module [sap-btp-naming-conventions-subaccount](../../modules/sap-btp-naming-conventions-subaccount/README.md). The names and labels are derived based on input variables defined in the [variables.tf](./variables.tf) file.
+
+### Validations for Geographies and BTP Regions
+
+According to the SAP BTP Administrators Guide one part of the naming is the geographical region. To ensure that this region fits to the subaccount region, a validation is implemented in the [variables.tf](./variables.tf) file. The validation checks if the region of the subaccount is part of the geographical region. The geographical regions are defined in a local variables defined in the [main.tf](main.tf) file.
+
+### Setup of Entitlements
+
+The setup of entitlements is split into two parts:
+
+- The default entitlements that are defined per stage and sourced from the module [](../../modules/sap-btp-subaccount-default-entitlements/README.md)
+- Optional additional entitlements that might be needed due to project specific requirements. These entitlements are defined in the [variables.tf](./variables.tf) file
+
+The configuration merges the two files and adds the entitlements to the subaccount.
+
+To ease the provisioning of entitlements we use the Terraform community module [SAP BTP Entitlements Management with Terraform Module: sap-btp-entitlements](https://registry.terraform.io/modules/aydin-ozcan/sap-btp-entitlements/btp/latest).
+
+### Setup of Cloud Foundry Environment
+
+The setup of a Cloud Foundry environment is optional. The caller can decide if a Cloud Foundry environment is required or not e.g. when setting up a shared subaccount. The boolean variable is `provision_cf_environment` in the [variables.tf](./variables.tf) file.
+
+
+### Output
+
+The output defined in the [outputs.tf](./outputs.tf) file returns the main information relevant for the development team namely:
+
+- a link to the subaccount
+- The ID of the Cloud Foundry org
+- The API endpoint of the Cloud Foundry environment
+
+
+
+## SAP BTP Administrator's Guide - References
+
+- [Setting Up Your Account Model](https://help.sap.com/docs/btp/btp-admin-guide/setting-up-your-account-model)
+- [Naming and Directory Templates](https://help.sap.com/docs/btp/btp-admin-guide/naming-directory-templates)
+- [Setting Up Authentication](https://help.sap.com/docs/btp/btp-admin-guide/setting-up-authentication)
+- [Cloud Foundry, Kyma, or Both?](https://help.sap.com/docs/btp/btp-admin-guide/cloudfoundry-kyma-or-both)
diff --git a/sample-setups/basic-setup/subaccount-setup/main.tf b/sample-setups/basic-setup/subaccount-setup/main.tf
new file mode 100644
index 0000000..12bc390
--- /dev/null
+++ b/sample-setups/basic-setup/subaccount-setup/main.tf
@@ -0,0 +1,80 @@
+locals {
+ valid_region_combination = {
+ eu10 = "EMEA"
+ eu11 = "EMEA"
+ eu20 = "EMEA"
+ eu30 = "EMEA"
+ us10 = "AMER"
+ us11 = "AMER"
+ us20 = "AMER"
+ us21 = "AMER"
+ us30 = "AMER"
+ ap10 = "APAC"
+ ap11 = "APAC"
+ ap12 = "APAC"
+ ap20 = "APAC"
+ ap12 = "APAC"
+ ap30 = "APAC"
+ }
+}
+
+data "btp_globalaccount" "this" {}
+
+module "subaccount_namings" {
+ source = "../../modules/sap-btp-naming-conventions-subaccount"
+ business_unit = var.business_unit
+ costcenter = var.costcenter
+ stage = var.stage
+ subaccount_contacts = var.subaccount_contacts
+}
+
+resource "btp_subaccount" "self" {
+ parent_id = var.parent_id
+ name = module.subaccount_namings.subaccount_name
+ subdomain = module.subaccount_namings.subaccount_subdomain
+ region = var.subaccount_region
+ description = module.subaccount_namings.subaccount_description
+ usage = module.subaccount_namings.subaccount_usage
+ labels = module.subaccount_namings.subaccount_labels
+}
+
+resource "btp_subaccount_trust_configuration" "custom_idp" {
+ subaccount_id = btp_subaccount.self.id
+ identity_provider = var.custom_indentity_provider
+ name = "default-corp-custom-idp"
+ description = "Default Custom IdP of Corporate"
+ auto_create_shadow_users = true
+ available_for_user_logon = true
+}
+
+module "subaccount_default_entitlements" {
+ source = "../../modules/sap-btp-subaccount-default-entitlements"
+
+ stage = var.stage
+}
+
+locals {
+ finalized_entitlements = var.additional_entitlements == {} ? module.subaccount_default_entitlements.default_entitlements_for_stage : merge(
+ module.subaccount_default_entitlements.default_entitlements_for_stage,
+ var.additional_entitlements
+ )
+}
+
+module "sap_btp_entitlements" {
+
+ source = "aydin-ozcan/sap-btp-entitlements/btp"
+ version = "~> 1.0.1"
+
+ subaccount = btp_subaccount.self.id
+ entitlements = local.finalized_entitlements
+}
+
+module "cf_environment" {
+ source = "../../modules/sap-btp-environment/CloudFoundry"
+
+ count = var.provision_cf_environment ? 1 : 0
+
+ subaccount_id = btp_subaccount.self.id
+ instance_name = module.subaccount_namings.cloudfoundry_org_name
+ cf_org_name = module.subaccount_namings.cloudfoundry_org_name
+}
diff --git a/sample-setups/basic-setup/subaccount-setup/outputs.tf b/sample-setups/basic-setup/subaccount-setup/outputs.tf
new file mode 100644
index 0000000..136e2c4
--- /dev/null
+++ b/sample-setups/basic-setup/subaccount-setup/outputs.tf
@@ -0,0 +1,14 @@
+output "subaccount_url" {
+ value = "https://emea.cockpit.btp.cloud.sap/cockpit/#globalaccount/${data.btp_globalaccount.this.id}/subaccount/${btp_subaccount.self.id}/overview"
+ description = "The URL to the provisioned subaccount on SAP BTP"
+}
+
+output "cf_api_url" {
+ value = var.provision_cf_environment ? module.cf_environment[0].cf_api_url : "No Cloud Foundry environment was requested to be provisioned"
+ description = "The Cloud Foundry API URL"
+}
+
+output "cf_org_id" {
+ value = var.provision_cf_environment ? module.cf_environment[0].cf_org_id : "No Cloud Foundry environment was requested to be provisioned"
+ description = "The Cloud Foundry org ID"
+}
diff --git a/sample-setups/basic-setup/subaccount-setup/provider.tf b/sample-setups/basic-setup/subaccount-setup/provider.tf
new file mode 100644
index 0000000..52f55ff
--- /dev/null
+++ b/sample-setups/basic-setup/subaccount-setup/provider.tf
@@ -0,0 +1,13 @@
+terraform {
+ required_providers {
+ btp = {
+ source = "SAP/btp"
+ version = "~>1.11.0"
+ }
+ }
+}
+
+# Configure the BTP Provider
+provider "btp" {
+ globalaccount = var.globalaccount
+}
diff --git a/sample-setups/basic-setup/subaccount-setup/variables.tf b/sample-setups/basic-setup/subaccount-setup/variables.tf
new file mode 100644
index 0000000..0b29175
--- /dev/null
+++ b/sample-setups/basic-setup/subaccount-setup/variables.tf
@@ -0,0 +1,78 @@
+variable "globalaccount" {
+ type = string
+ description = "The subdomain of the global account on SAP BTP"
+}
+
+variable "business_unit" {
+ type = string
+ description = "Business unit of the project e.g., HR, IT or Sales"
+}
+
+variable "region" {
+ type = string
+ default = null
+ description = <<-EOT
+ The geographical region for a directory. The parameter is optional
+ If you set it the possible values are: `EMEA`, `APAC`, `AMER`.
+ Default value: `null`.
+ EOT
+}
+
+variable "subaccount_region" {
+ type = string
+ description = "Region of the subaccount."
+ validation {
+ condition = lookup(local.valid_region_combination, var.subaccount_region, "INVALID") == var.region
+ error_message = "Please provide a fitting subaccount region for the region"
+ }
+}
+
+variable "costcenter" {
+ type = string
+ description = "Cost center to be used for subaccounts"
+}
+
+variable "company_name" {
+ type = string
+ description = <<-EOT
+ Company name to be used for subaccount subdomains. The parameter is optional
+ Default value: `null`.
+ EOT
+ default = null
+}
+
+variable "stage" {
+ type = string
+ description = <<-EOT
+ Stage of the environment to be setup up.
+ Possible values: `Dev`, `Test`, `Prod`, `Shared`.
+ EOT
+}
+
+variable "subaccount_contacts" {
+ type = list(string)
+ description = "Contact persons to be used for subaccount, added as label"
+}
+
+variable "parent_id" {
+ type = string
+ description = "ID of the parent directory"
+ default = null
+}
+
+variable "custom_indentity_provider" {
+ type = string
+ description = "Custom IdP to be used for subaccount"
+}
+
+variable "additional_entitlements" {
+ type = map(list(string))
+ description = "Entitlements to be provided in addition to the standard entitlements"
+ default = {}
+}
+
+variable "provision_cf_environment" {
+ type = bool
+ description = "Provision Cloud Foundry environment in subaccount"
+ default = true
+}
diff --git a/sample-setups/modules/base-directory-setup/.terraform.lock.hcl b/sample-setups/modules/base-directory-setup/.terraform.lock.hcl
new file mode 100644
index 0000000..1da39de
--- /dev/null
+++ b/sample-setups/modules/base-directory-setup/.terraform.lock.hcl
@@ -0,0 +1,25 @@
+# This file is maintained automatically by "terraform init".
+# Manual edits may be lost in future updates.
+
+provider "registry.terraform.io/sap/btp" {
+ version = "1.11.0"
+ constraints = ">= 1.11.0"
+ hashes = [
+ "h1:q9XDheshVlSVbcWKmAlOjF+EGTxvpgS+CyMOyPzh3uw=",
+ "zh:16647cac2e5062c4ac9db89d622b1de3375e57372841f65f3e6997a26a2f283d",
+ "zh:548d023762dbd3c2830a151f0beadf58401a70368299625f4c90100997348aed",
+ "zh:55aba6fba636e2d6524f4b180fb1ff0df6328dd3812682726a0b9972c921dbdf",
+ "zh:624fb982f4cfb2c26b1448e6270b6ad891592e4e52a00718781579fb5a079adb",
+ "zh:6319aa5b8c60c3916eff4142ecf6f297a8baf1bc903c98a29b6c248a3984f488",
+ "zh:7979a475dd06d12255269fe6ec004d1c460bb64869a9d814bec58bec88b65147",
+ "zh:967b5d6b71053e19dbb017319b8b8bd84d8c7f7cfba6fbb4b23243ce860c370e",
+ "zh:97b02bc0cd9d74bbf4b89b4f8cd9508f0eec7b772b88704f70b696c425a5165e",
+ "zh:a398f2697184f49cb5e32a6c7b3f586a8a723a2d533a4cc13e11d8739fabf6b2",
+ "zh:b9e0a0a986cf8a790c10d469f61c81e9cfc41f4a188f060fb1c5a7612101a4da",
+ "zh:d03b1276c08f7b9d5da9d89505d1a71c0f806142ef336f26abd85a144a68b895",
+ "zh:dd6e32cf30f53707fec2acb1e5c69c044a76349706785bfcdee8fbaa6bb053c6",
+ "zh:e7afd57c00ba45a6be5005620e44db08eec2e6adb97b0af1ffb57963767f8229",
+ "zh:f29dc297897b96bf39f4b6737e6b9e2b8339c3ddc362fc5466ce901d84ef8cb9",
+ "zh:f6057496ac45093be445ed8423dc9dfcdbb21e5cc6d6348dbe3a8d5641882f3f",
+ ]
+}
diff --git a/sample-setups/modules/base-directory-setup/README.md b/sample-setups/modules/base-directory-setup/README.md
new file mode 100644
index 0000000..ce840ef
--- /dev/null
+++ b/sample-setups/modules/base-directory-setup/README.md
@@ -0,0 +1,47 @@
+# SAP BTP - Directory Setup
+
+This module encapsulates the creation of a directory on SAP BTP following standardized naming conventions.
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.11 |
+| [btp](#requirement\_btp) | >= 1.11.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [btp](#provider\_btp) | 1.11.0 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [dir\_namings](#module\_dir\_namings) | ../sap-btp-naming-conventions-directory | n/a |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [btp_directory.self](https://registry.terraform.io/providers/SAP/btp/latest/docs/resources/directory) | resource |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [business\_unit](#input\_business\_unit) | Business unit of the project e.g., HR, IT or Sales | `string` | n/a | yes |
+| [costcenter](#input\_costcenter) | Cost center to be used for subaccounts | `string` | n/a | yes |
+| [directory\_contacts](#input\_directory\_contacts) | Contact persons to be used for directory, added as label | `list(string)` | n/a | yes |
+| [region](#input\_region) | The geographical region for a directory. The parameter is optional
If you set it the possible values are: `EMEA`, `APAC`, `AMER`.
Default value: `null`. | `string` | `null` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [business\_unit](#output\_business\_unit) | Business unit of the project e.g., HR, IT or Sales |
+| [costcenter](#output\_costcenter) | Cost center to be used for subaccounts |
+| [directory\_id](#output\_directory\_id) | Technical ID of the directory |
+| [directory\_name](#output\_directory\_name) | The name of the directory |
+| [region](#output\_region) | The geographical region for a directory. The parameter is optional |
diff --git a/sample-setups/modules/base-directory-setup/main.tf b/sample-setups/modules/base-directory-setup/main.tf
new file mode 100644
index 0000000..d2cd72c
--- /dev/null
+++ b/sample-setups/modules/base-directory-setup/main.tf
@@ -0,0 +1,14 @@
+module "dir_namings" {
+ source = "../sap-btp-naming-conventions-directory"
+ business_unit = var.business_unit
+ costcenter = var.costcenter
+ directory_contacts = var.directory_contacts
+ region = var.region
+}
+
+
+resource "btp_directory" "self" {
+ name = module.dir_namings.directory_name
+ description = module.dir_namings.directory_description
+ labels = module.dir_namings.directory_labels
+}
diff --git a/sample-setups/modules/base-directory-setup/outputs.tf b/sample-setups/modules/base-directory-setup/outputs.tf
new file mode 100644
index 0000000..085eab8
--- /dev/null
+++ b/sample-setups/modules/base-directory-setup/outputs.tf
@@ -0,0 +1,24 @@
+output "directory_id" {
+ value = btp_directory.self.id
+ description = "Technical ID of the directory"
+}
+
+output "directory_name" {
+ value = btp_directory.self.name
+ description = "The name of the directory"
+}
+
+output "business_unit" {
+ value = var.business_unit
+ description = "Business unit of the project e.g., HR, IT or Sales"
+}
+
+output "costcenter" {
+ value = var.costcenter
+ description = "Cost center to be used for subaccounts"
+}
+
+output "region" {
+ value = var.region
+ description = "The geographical region for a directory. The parameter is optional"
+}
diff --git a/sample-setups/modules/base-directory-setup/variables.tf b/sample-setups/modules/base-directory-setup/variables.tf
new file mode 100644
index 0000000..d26d95a
--- /dev/null
+++ b/sample-setups/modules/base-directory-setup/variables.tf
@@ -0,0 +1,24 @@
+variable "business_unit" {
+ type = string
+ description = "Business unit of the project e.g., HR, IT or Sales"
+}
+
+variable "region" {
+ type = string
+ default = null
+ description = <<-EOT
+ The geographical region for a directory. The parameter is optional
+ If you set it the possible values are: `EMEA`, `APAC`, `AMER`.
+ Default value: `null`.
+ EOT
+}
+
+variable "costcenter" {
+ type = string
+ description = "Cost center to be used for subaccounts"
+}
+
+variable "directory_contacts" {
+ type = list(string)
+ description = "Contact persons to be used for directory, added as label"
+}
diff --git a/sample-setups/modules/base-directory-setup/versions.tf b/sample-setups/modules/base-directory-setup/versions.tf
new file mode 100644
index 0000000..9bbde7b
--- /dev/null
+++ b/sample-setups/modules/base-directory-setup/versions.tf
@@ -0,0 +1,9 @@
+terraform {
+ required_version = ">= 1.11"
+ required_providers {
+ btp = {
+ source = "SAP/btp"
+ version = ">= 1.11.0"
+ }
+ }
+}
diff --git a/sample-setups/modules/sap-btp-environment/CloudFoundry/README.md b/sample-setups/modules/sap-btp-environment/CloudFoundry/README.md
new file mode 100644
index 0000000..ceb9464
--- /dev/null
+++ b/sample-setups/modules/sap-btp-environment/CloudFoundry/README.md
@@ -0,0 +1,45 @@
+# SAP BTP - Environment Setup
+
+This module encapsulates the creation of a Cloud Foundry environment in a subaccount on SAP BTP.
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.11 |
+| [btp](#requirement\_btp) | >= 1.11.0 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [btp](#provider\_btp) | >= 1.11.0 |
+| [null](#provider\_null) | n/a |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [btp_subaccount_environment_instance.self](https://registry.terraform.io/providers/SAP/btp/latest/docs/resources/subaccount_environment_instance) | resource |
+| [null_resource.cache_target_environment](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
+| [btp_subaccount_environments.all](https://registry.terraform.io/providers/SAP/btp/latest/docs/data-sources/subaccount_environments) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [cf\_org\_name](#input\_cf\_org\_name) | Name of the Cloud Foundry org. | `string` | n/a | yes |
+| [instance\_name](#input\_instance\_name) | Name of the Cloud Foundry environment instance. | `string` | n/a | yes |
+| [plan\_name](#input\_plan\_name) | Desired service plan for the Cloud Foundry environment instance. | `string` | `"standard"` | no |
+| [subaccount\_id](#input\_subaccount\_id) | ID of the subaccount where the Cloud Foundry environment will be created. | `string` | n/a | yes |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [cf\_api\_url](#output\_cf\_api\_url) | The Cloud Foundry API URL |
+| [cf\_org\_id](#output\_cf\_org\_id) | The Cloud Foundry org ID |
diff --git a/sample-setups/modules/sap-btp-environment/CloudFoundry/main.tf b/sample-setups/modules/sap-btp-environment/CloudFoundry/main.tf
new file mode 100644
index 0000000..0d9ccaf
--- /dev/null
+++ b/sample-setups/modules/sap-btp-environment/CloudFoundry/main.tf
@@ -0,0 +1,26 @@
+data "btp_subaccount_environments" "all" {
+ subaccount_id = var.subaccount_id
+}
+
+resource "null_resource" "cache_target_environment" {
+ triggers = {
+ label = [for env in data.btp_subaccount_environments.all.values : env if env.service_name == "cloudfoundry" && env.environment_type == "cloudfoundry"][0].landscape_label
+ }
+
+ lifecycle {
+ ignore_changes = all
+ }
+}
+
+resource "btp_subaccount_environment_instance" "self" {
+ subaccount_id = var.subaccount_id
+ name = var.instance_name
+ environment_type = "cloudfoundry"
+ service_name = "cloudfoundry"
+ plan_name = var.plan_name
+ landscape_label = null_resource.cache_target_environment.triggers.label
+
+ parameters = jsonencode({
+ instance_name = var.cf_org_name
+ })
+}
diff --git a/sample-setups/modules/sap-btp-environment/CloudFoundry/outputs.tf b/sample-setups/modules/sap-btp-environment/CloudFoundry/outputs.tf
new file mode 100644
index 0000000..36140e8
--- /dev/null
+++ b/sample-setups/modules/sap-btp-environment/CloudFoundry/outputs.tf
@@ -0,0 +1,9 @@
+output "cf_api_url" {
+ value = jsondecode(btp_subaccount_environment_instance.self.labels)["API Endpoint"]
+ description = "The Cloud Foundry API URL"
+}
+
+output "cf_org_id" {
+ value = jsondecode(btp_subaccount_environment_instance.self.labels)["Org ID"]
+ description = "The Cloud Foundry org ID"
+}
diff --git a/sample-setups/modules/sap-btp-environment/CloudFoundry/variables.tf b/sample-setups/modules/sap-btp-environment/CloudFoundry/variables.tf
new file mode 100644
index 0000000..5500b45
--- /dev/null
+++ b/sample-setups/modules/sap-btp-environment/CloudFoundry/variables.tf
@@ -0,0 +1,29 @@
+variable "subaccount_id" {
+ type = string
+ description = "ID of the subaccount where the Cloud Foundry environment will be created."
+}
+variable "instance_name" {
+ type = string
+ description = "Name of the Cloud Foundry environment instance."
+
+ validation {
+ condition = can(regex("^[a-zA-Z0-9_\\-\\.]{1,32}$", var.instance_name))
+ error_message = "Please provide a valid instance name (^[a-zA-Z0-9_\\-\\.]{1,32})."
+ }
+}
+
+variable "plan_name" {
+ type = string
+ description = "Desired service plan for the Cloud Foundry environment instance."
+ default = "standard"
+}
+
+variable "cf_org_name" {
+ type = string
+ description = "Name of the Cloud Foundry org."
+
+ validation {
+ condition = can(regex("^.{1,255}$", var.cf_org_name))
+ error_message = "The Cloud Foundry org name must not be emtpy and not exceed 255 characters."
+ }
+}
diff --git a/sample-setups/modules/sap-btp-environment/CloudFoundry/versions.tf b/sample-setups/modules/sap-btp-environment/CloudFoundry/versions.tf
new file mode 100644
index 0000000..9bbde7b
--- /dev/null
+++ b/sample-setups/modules/sap-btp-environment/CloudFoundry/versions.tf
@@ -0,0 +1,9 @@
+terraform {
+ required_version = ">= 1.11"
+ required_providers {
+ btp = {
+ source = "SAP/btp"
+ version = ">= 1.11.0"
+ }
+ }
+}
diff --git a/sample-setups/modules/sap-btp-naming-conventions-directory/README.md b/sample-setups/modules/sap-btp-naming-conventions-directory/README.md
new file mode 100644
index 0000000..1ef08ee
--- /dev/null
+++ b/sample-setups/modules/sap-btp-naming-conventions-directory/README.md
@@ -0,0 +1,31 @@
+# SAP BTP - Naming Conventions for a Directory
+
+This module encapsulates the naming conventions for SAP BTP directories and the labels that can be attached to some resources on SAP BTP.
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.11 |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [add\_managed\_by\_label](#input\_add\_managed\_by\_label) | Add label that resource is managed by Terraform | `bool` | `true` | no |
+| [business\_unit](#input\_business\_unit) | Business unit of the project e.g., HR, IT or Sales | `string` | n/a | yes |
+| [costcenter](#input\_costcenter) | Cost center to be used for subaccounts | `string` | n/a | yes |
+| [delimiter](#input\_delimiter) | Delimiter to be used for namings | `string` | `"-"` | no |
+| [directory\_contacts](#input\_directory\_contacts) | Contact persons to be used for directories, added as label | `list(string)` | n/a | yes |
+| [label\_name\_case](#input\_label\_name\_case) | Controls the letter case of the `label` names for labels generated by this module.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `"title"` | no |
+| [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of the `label` values for labels generated by this module.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Default value: `lower`. | `string` | `"lower"` | no |
+| [management\_tool](#input\_management\_tool) | Defines which tool is used for management of infrastructure.
Possible values: `Terraform`, `OpenTofu`.
Default value: `Terraform`. | `string` | `"Terraform"` | no |
+| [region](#input\_region) | The geographical region for a directory. The parameter is optional
If you set it the possible values are: `EMEA`, `APAC`, `AMER`.
Default value: `null`. | `string` | `null` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [directory\_description](#output\_directory\_description) | Description of the directory |
+| [directory\_labels](#output\_directory\_labels) | Labels for the directory |
+| [directory\_name](#output\_directory\_name) | Name of the directory |
diff --git a/sample-setups/modules/sap-btp-naming-conventions-directory/main.tf b/sample-setups/modules/sap-btp-naming-conventions-directory/main.tf
new file mode 100644
index 0000000..8443281
--- /dev/null
+++ b/sample-setups/modules/sap-btp-naming-conventions-directory/main.tf
@@ -0,0 +1,46 @@
+locals {
+ costcenter_label_name = "Costcenter"
+ directory_contact_label_name = "Directory responsibles"
+ managedby_label_name = "Managed by"
+
+ directory_name = var.region == null ? var.business_unit : format(
+ "%s%s%s",
+ upper(var.business_unit),
+ var.delimiter,
+ var.region
+ )
+
+ directory_description = var.region == null ? format(
+ "Directory for business Unit %s",
+ var.business_unit
+ ) : format(
+ "Directory for business Unit %s (%s)",
+ var.business_unit,
+ var.region
+ )
+
+ costcenter_label_name_formatted = var.label_name_case == "lower" ? lower(local.costcenter_label_name) : var.label_name_case == "title" ? title(local.costcenter_label_name) : upper(local.costcenter_label_name)
+ directory_contact_label_name_formatted = var.label_name_case == "lower" ? lower(local.directory_contact_label_name) : var.label_name_case == "title" ? title(local.directory_contact_label_name) : upper(local.directory_contact_label_name)
+ managedby_label_name_formatted = var.label_name_case == "lower" ? lower(local.managedby_label_name) : var.label_name_case == "title" ? title(local.managedby_label_name) : upper(local.managedby_label_name)
+
+ costcenter_label_value_formatted = var.label_value_case == "lower" ? lower(var.costcenter) : var.label_value_case == "title" ? title(var.costcenter) : var.label_value_case == "upper" ? upper(var.costcenter) : var.costcenter
+ management_label_value_formatted = var.label_value_case == "lower" ? lower(var.management_tool) : var.label_value_case == "title" ? title(var.management_tool) : var.label_value_case == "upper" ? upper(var.management_tool) : var.management_tool
+
+ basic_labels = {
+ "${local.costcenter_label_name_formatted}" = [local.costcenter_label_value_formatted]
+ }
+
+ basic_labels_final = var.add_managed_by_label ? merge(
+ local.basic_labels,
+ {
+ "${local.managedby_label_name_formatted}" = [local.management_label_value_formatted]
+ }
+ ) : local.basic_labels
+
+ directory_labels = merge(
+ local.basic_labels_final,
+ {
+ "${local.directory_contact_label_name_formatted}" = var.directory_contacts
+ }
+ )
+}
diff --git a/sample-setups/modules/sap-btp-naming-conventions-directory/outputs.tf b/sample-setups/modules/sap-btp-naming-conventions-directory/outputs.tf
new file mode 100644
index 0000000..e1482a5
--- /dev/null
+++ b/sample-setups/modules/sap-btp-naming-conventions-directory/outputs.tf
@@ -0,0 +1,29 @@
+output "directory_name" {
+ value = local.directory_name
+ description = "Name of the directory"
+}
+
+output "directory_description" {
+ value = local.directory_description
+ description = "Description of the directory"
+}
+
+output "directory_labels" {
+ value = local.directory_labels
+ description = "Labels for the directory"
+}
+
+output "business_unit" {
+ value = var.business_unit
+ description = "Business unit of the project e.g., HR, IT or Sales"
+}
+
+output "costcenter" {
+ value = var.costcenter
+ description = "Cost center to be used for subaccounts"
+}
+
+output "region" {
+ value = var.region
+ description = "The geographical region for a directory. The parameter is optional"
+}
diff --git a/sample-setups/modules/sap-btp-naming-conventions-directory/variables.tf b/sample-setups/modules/sap-btp-naming-conventions-directory/variables.tf
new file mode 100644
index 0000000..8527a3c
--- /dev/null
+++ b/sample-setups/modules/sap-btp-naming-conventions-directory/variables.tf
@@ -0,0 +1,86 @@
+variable "business_unit" {
+ type = string
+ description = "Business unit of the project e.g., HR, IT or Sales"
+}
+
+variable "region" {
+ type = string
+ default = null
+ description = <<-EOT
+ The geographical region for a directory. The parameter is optional
+ If you set it the possible values are: `EMEA`, `APAC`, `AMER`.
+ Default value: `null`.
+ EOT
+
+ validation {
+ condition = var.region == null ? true : contains(["EMEA", "APAC", "AMER"], var.region)
+ error_message = "Allowed values are: `EMEA`, `APAC`, `AMER`."
+ }
+}
+
+variable "costcenter" {
+ type = string
+ description = "Cost center to be used for subaccounts"
+}
+
+variable "directory_contacts" {
+ type = list(string)
+ description = "Contact persons to be used for directories, added as label"
+}
+
+variable "add_managed_by_label" {
+ type = bool
+ description = "Add label that resource is managed by Terraform"
+ default = true
+}
+
+variable "management_tool" {
+ type = string
+ description = <<-EOT
+ Defines which tool is used for management of infrastructure.
+ Possible values: `Terraform`, `OpenTofu`.
+ Default value: `Terraform`.
+ EOT
+
+ validation {
+ condition = contains(["Terraform", "OpenTofu"], var.management_tool)
+ error_message = "Allowed values are: `Terraform`, `OpenTofu`."
+ }
+ default = "Terraform"
+}
+
+variable "delimiter" {
+ type = string
+ description = "Delimiter to be used for namings"
+ default = "-"
+}
+
+variable "label_name_case" {
+ type = string
+ default = "title"
+ description = <<-EOT
+ Controls the letter case of the `label` names for labels generated by this module.
+ Possible values: `lower`, `title`, `upper`.
+ Default value: `title`.
+ EOT
+
+ validation {
+ condition = contains(["lower", "title", "upper"], var.label_name_case)
+ error_message = "Allowed values are: `lower`, `title`, `upper`."
+ }
+}
+
+variable "label_value_case" {
+ type = string
+ default = "lower"
+ description = <<-EOT
+ Controls the letter case of the `label` values for labels generated by this module.
+ Possible values: `lower`, `title`, `upper` and `none` (no transformation).
+ Default value: `lower`.
+ EOT
+
+ validation {
+ condition = contains(["lower", "title", "upper", "none"], var.label_value_case)
+ error_message = "Allowed values are: `lower`, `title`, `upper`, `none`."
+ }
+}
diff --git a/sample-setups/modules/sap-btp-naming-conventions-directory/versions.tf b/sample-setups/modules/sap-btp-naming-conventions-directory/versions.tf
new file mode 100644
index 0000000..2dc2c98
--- /dev/null
+++ b/sample-setups/modules/sap-btp-naming-conventions-directory/versions.tf
@@ -0,0 +1,3 @@
+terraform {
+ required_version = ">= 1.11"
+}
diff --git a/sample-setups/modules/sap-btp-naming-conventions-subaccount/README.md b/sample-setups/modules/sap-btp-naming-conventions-subaccount/README.md
new file mode 100644
index 0000000..5f498a1
--- /dev/null
+++ b/sample-setups/modules/sap-btp-naming-conventions-subaccount/README.md
@@ -0,0 +1,51 @@
+# SAP BTP - Naming Conventions for a Subaccount
+
+This module encapsulates the naming conventions for SAP BTP subaccounts and the labels that can be attached to some resources on SAP BTP.
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.11 |
+
+## Providers
+
+| Name | Version |
+|------|---------|
+| [random](#provider\_random) | n/a |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [random_uuid.self](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/uuid) | resource |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [add\_managed\_by\_label](#input\_add\_managed\_by\_label) | Add label that resource is managed by Terraform | `bool` | `true` | no |
+| [business\_unit](#input\_business\_unit) | Business unit of the project e.g., HR, IT or Sales | `string` | n/a | yes |
+| [company\_name](#input\_company\_name) | Company name to be used for subaccount subdomains. The parameter is optional
Default value: `null`. | `string` | `null` | no |
+| [costcenter](#input\_costcenter) | Cost center to be used for subaccounts | `string` | n/a | yes |
+| [delimiter](#input\_delimiter) | Delimiter to be used for namings | `string` | `"-"` | no |
+| [label\_name\_case](#input\_label\_name\_case) | Controls the letter case of the `label` names for labels generated by this module.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `"title"` | no |
+| [label\_value\_case](#input\_label\_value\_case) | Controls the letter case of the `label` values for labels generated by this module.
Possible values: `lower`, `title`, `upper` and `none` (no transformation).
Default value: `lower`. | `string` | `"lower"` | no |
+| [management\_tool](#input\_management\_tool) | Defines which tool is used for management of infrastructure.
Possible values: `Terraform`, `OpenTofu`.
Default value: `Terraform`. | `string` | `"Terraform"` | no |
+| [stage](#input\_stage) | Stage of the environment to be setup up.
Possible values: `Dev`, `Test`, `Prod`, `Shared`. | `string` | n/a | yes |
+| [subaccount\_contacts](#input\_subaccount\_contacts) | Contact persons to be used for subaccounts, added as label | `list(string)` | n/a | yes |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [cloudfoundry\_org\_name](#output\_cloudfoundry\_org\_name) | Name of the Cloud Foundry org |
+| [subaccount\_description](#output\_subaccount\_description) | Description of the subaccount |
+| [subaccount\_labels](#output\_subaccount\_labels) | Labels for the subaccount |
+| [subaccount\_name](#output\_subaccount\_name) | Name of the subaccount |
+| [subaccount\_subdomain](#output\_subaccount\_subdomain) | Subdomain of the subaccount |
+| [subaccount\_usage](#output\_subaccount\_usage) | Usage of the subaccount |
diff --git a/sample-setups/modules/sap-btp-naming-conventions-subaccount/main.tf b/sample-setups/modules/sap-btp-naming-conventions-subaccount/main.tf
new file mode 100644
index 0000000..df37bde
--- /dev/null
+++ b/sample-setups/modules/sap-btp-naming-conventions-subaccount/main.tf
@@ -0,0 +1,84 @@
+resource "random_uuid" "self" {
+}
+
+locals {
+ # The length limit for the subdomain is 63 characters.
+ subdomain_length_limit = 63
+ costcenter_label_name = "Costcenter"
+ subaccount_contact_label_name = "Subaccount responsibles"
+ stage_label_name = "Stage"
+ managedby_label_name = "Managed by"
+
+ costcenter_label_name_formatted = var.label_name_case == "lower" ? lower(local.costcenter_label_name) : var.label_name_case == "title" ? title(local.costcenter_label_name) : upper(local.costcenter_label_name)
+ subaccount_contact_label_name_formatted = var.label_name_case == "lower" ? lower(local.subaccount_contact_label_name) : var.label_name_case == "title" ? title(local.subaccount_contact_label_name) : upper(local.subaccount_contact_label_name)
+ stage_label_name_formatted = var.label_name_case == "lower" ? lower(local.stage_label_name) : var.label_name_case == "title" ? title(local.stage_label_name) : upper(local.stage_label_name)
+ managedby_label_name_formatted = var.label_name_case == "lower" ? lower(local.managedby_label_name) : var.label_name_case == "title" ? title(local.managedby_label_name) : upper(local.managedby_label_name)
+
+ costcenter_label_value_formatted = var.label_value_case == "lower" ? lower(var.costcenter) : var.label_value_case == "title" ? title(var.costcenter) : var.label_value_case == "upper" ? upper(var.costcenter) : var.costcenter
+ stage_label_value_formatted = var.label_value_case == "lower" ? lower(var.stage) : var.label_value_case == "title" ? title(var.stage) : var.label_value_case == "upper" ? upper(var.stage) : var.stage
+ management_label_value_formatted = var.label_value_case == "lower" ? lower(var.management_tool) : var.label_value_case == "title" ? title(var.management_tool) : var.label_value_case == "upper" ? upper(var.management_tool) : var.management_tool
+
+ basic_labels = {
+ "${local.costcenter_label_name_formatted}" = [local.costcenter_label_value_formatted]
+ "${local.stage_label_name_formatted}" = [local.stage_label_value_formatted]
+ }
+
+ basic_labels_final = var.add_managed_by_label ? merge(
+ local.basic_labels,
+ {
+ "${local.managedby_label_name_formatted}" = [local.management_label_value_formatted]
+ }
+ ) : local.basic_labels
+
+ subaccount_name = format(
+ "%s%s%s",
+ lower(var.business_unit),
+ var.delimiter,
+ lower(var.stage)
+ )
+
+ subaccount_subdomain_base = var.company_name == null ? format(
+ "%s%s%s",
+ lower(var.business_unit),
+ var.delimiter,
+ lower(var.stage)
+ ) : format(
+ "%s%s%s%s%s",
+ lower(var.company_name),
+ var.delimiter,
+ lower(var.business_unit),
+ var.delimiter,
+ lower(var.stage)
+ )
+
+ subaccount_sudomain_with_UUID = format(
+ "%s%s%s",
+ local.subaccount_subdomain_base,
+ var.delimiter,
+ random_uuid.self.id
+ )
+
+ subaccount_subdomain = length(local.subaccount_sudomain_with_UUID) > local.subdomain_length_limit ? substr(
+ local.subaccount_sudomain_with_UUID,
+ 0,
+ local.subdomain_length_limit
+ ) : local.subaccount_sudomain_with_UUID
+
+
+ subaccount_description = format(
+ "Subaccount for Business Unit %s (%s)",
+ upper(var.business_unit),
+ title(lower(var.stage))
+ )
+
+ subaccount_labels = merge(
+ local.basic_labels_final,
+ {
+ "${local.subaccount_contact_label_name_formatted}" = var.subaccount_contacts
+ }
+ )
+
+ subaccount_usage = var.stage == "Prod" ? "USED_FOR_PRODUCTION" : "NOT_USED_FOR_PRODUCTION"
+
+ cloudfoundry_org_name = substr(local.subaccount_subdomain, 0, 32)
+}
diff --git a/sample-setups/modules/sap-btp-naming-conventions-subaccount/outputs.tf b/sample-setups/modules/sap-btp-naming-conventions-subaccount/outputs.tf
new file mode 100644
index 0000000..a7297f4
--- /dev/null
+++ b/sample-setups/modules/sap-btp-naming-conventions-subaccount/outputs.tf
@@ -0,0 +1,29 @@
+output "subaccount_name" {
+ value = local.subaccount_name
+ description = "Name of the subaccount"
+}
+
+output "subaccount_subdomain" {
+ value = local.subaccount_subdomain
+ description = "Subdomain of the subaccount"
+}
+
+output "subaccount_description" {
+ value = local.subaccount_description
+ description = "Description of the subaccount"
+}
+
+output "subaccount_labels" {
+ value = local.subaccount_labels
+ description = "Labels for the subaccount"
+}
+
+output "subaccount_usage" {
+ value = local.subaccount_usage
+ description = "Usage of the subaccount"
+}
+
+output "cloudfoundry_org_name" {
+ value = local.cloudfoundry_org_name
+ description = "Name of the Cloud Foundry org"
+}
diff --git a/sample-setups/modules/sap-btp-naming-conventions-subaccount/variables.tf b/sample-setups/modules/sap-btp-naming-conventions-subaccount/variables.tf
new file mode 100644
index 0000000..a7b4a1e
--- /dev/null
+++ b/sample-setups/modules/sap-btp-naming-conventions-subaccount/variables.tf
@@ -0,0 +1,93 @@
+variable "business_unit" {
+ type = string
+ description = "Business unit of the project e.g., HR, IT or Sales"
+}
+
+variable "stage" {
+ type = string
+ description = <<-EOT
+ Stage of the environment to be setup up.
+ Possible values: `Dev`, `Test`, `Prod`, `Shared`.
+ EOT
+
+ validation {
+ condition = contains(["Dev", "Test", "Prod", "Shared"], var.stage)
+ error_message = "Stage must be one of the following: `Dev`, `Test`, `Prod`, `Shared`."
+ }
+}
+
+variable "company_name" {
+ type = string
+ description = <<-EOT
+ Company name to be used for subaccount subdomains. The parameter is optional
+ Default value: `null`.
+ EOT
+ default = null
+}
+
+variable "costcenter" {
+ type = string
+ description = "Cost center to be used for subaccounts"
+}
+
+variable "subaccount_contacts" {
+ type = list(string)
+ description = "Contact persons to be used for subaccounts, added as label"
+}
+
+variable "add_managed_by_label" {
+ type = bool
+ description = "Add label that resource is managed by Terraform"
+ default = true
+}
+
+variable "management_tool" {
+ type = string
+ description = <<-EOT
+ Defines which tool is used for management of infrastructure.
+ Possible values: `Terraform`, `OpenTofu`.
+ Default value: `Terraform`.
+ EOT
+
+ validation {
+ condition = contains(["Terraform", "OpenTofu"], var.management_tool)
+ error_message = "Allowed values are: `Terraform`, `OpenTofu`."
+ }
+ default = "Terraform"
+}
+
+variable "delimiter" {
+ type = string
+ description = "Delimiter to be used for namings"
+ default = "-"
+}
+
+variable "label_name_case" {
+ type = string
+ default = "title"
+ description = <<-EOT
+ Controls the letter case of the `label` names for labels generated by this module.
+ Possible values: `lower`, `title`, `upper`.
+ Default value: `title`.
+ EOT
+
+ validation {
+ condition = contains(["lower", "title", "upper"], var.label_name_case)
+ error_message = "Allowed values are: `lower`, `title`, `upper`."
+ }
+}
+
+variable "label_value_case" {
+ type = string
+ default = "lower"
+ description = <<-EOT
+ Controls the letter case of the `label` values for labels generated by this module.
+ Possible values: `lower`, `title`, `upper` and `none` (no transformation).
+ Default value: `lower`.
+ EOT
+
+ validation {
+ condition = contains(["lower", "title", "upper", "none"], var.label_value_case)
+ error_message = "Allowed values are: `lower`, `title`, `upper`, `none`."
+ }
+}
diff --git a/sample-setups/modules/sap-btp-naming-conventions-subaccount/versions.tf b/sample-setups/modules/sap-btp-naming-conventions-subaccount/versions.tf
new file mode 100644
index 0000000..2dc2c98
--- /dev/null
+++ b/sample-setups/modules/sap-btp-naming-conventions-subaccount/versions.tf
@@ -0,0 +1,3 @@
+terraform {
+ required_version = ">= 1.11"
+}
diff --git a/sample-setups/modules/sap-btp-subaccount-default-entitlements/README.md b/sample-setups/modules/sap-btp-subaccount-default-entitlements/README.md
new file mode 100644
index 0000000..9ac8d35
--- /dev/null
+++ b/sample-setups/modules/sap-btp-subaccount-default-entitlements/README.md
@@ -0,0 +1,33 @@
+# SAP BTP - Default Subaccount Entitlements
+
+This module encapsulates the default entitlements for SAP BTP subaccounts. It distinguishes between the different stages of the environment (Dev, Test, Prod, Shared) and provides a default set of entitlements for each stage.
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.11 |
+
+## Providers
+
+No providers.
+
+## Modules
+
+No modules.
+
+## Resources
+
+No resources.
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [stage](#input\_stage) | Stage of the environment to be setup up.
Possible values: `Dev`, `Test`, `Prod`, `Shared`. | `string` | n/a | yes |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [default\_entitlements\_for\_stage](#output\_default\_entitlements\_for\_stage) | Default entitlements for stage specified by the stage variable |
diff --git a/sample-setups/modules/sap-btp-subaccount-default-entitlements/main.tf b/sample-setups/modules/sap-btp-subaccount-default-entitlements/main.tf
new file mode 100644
index 0000000..4acd7c0
--- /dev/null
+++ b/sample-setups/modules/sap-btp-subaccount-default-entitlements/main.tf
@@ -0,0 +1,25 @@
+locals {
+ default_entitlements = {
+ "Dev" = {
+ "alert-notification" = ["standard"],
+ "auditlog" = ["standard=1"],
+ "sapappstudio" = ["build-code"],
+ "xsuaa" = ["application"]
+ },
+ "Test" = {
+ "alert-notification" = ["standard"],
+ "auditlog" = ["standard=1"],
+ "xsuaa" = ["application"]
+ },
+ "Prod" = {
+ "alert-notification" = ["standard"],
+ "auditlog" = ["standard=1"],
+ "xsuaa" = ["application"]
+ },
+ "Shared" = {
+ "credstore" = ["standard"],
+ "hana-cloud" = ["hana"],
+ "hana" = ["hdi-shared"]
+ }
+ }
+}
diff --git a/sample-setups/modules/sap-btp-subaccount-default-entitlements/outputs.tf b/sample-setups/modules/sap-btp-subaccount-default-entitlements/outputs.tf
new file mode 100644
index 0000000..847f890
--- /dev/null
+++ b/sample-setups/modules/sap-btp-subaccount-default-entitlements/outputs.tf
@@ -0,0 +1,4 @@
+output "default_entitlements_for_stage" {
+ value = local.default_entitlements[var.stage]
+ description = "Default entitlements for stage specified by the stage variable"
+}
diff --git a/sample-setups/modules/sap-btp-subaccount-default-entitlements/variables.tf b/sample-setups/modules/sap-btp-subaccount-default-entitlements/variables.tf
new file mode 100644
index 0000000..ddbe7be
--- /dev/null
+++ b/sample-setups/modules/sap-btp-subaccount-default-entitlements/variables.tf
@@ -0,0 +1,12 @@
+variable "stage" {
+ type = string
+ description = <<-EOT
+ Stage of the environment to be setup up.
+ Possible values: `Dev`, `Test`, `Prod`, `Shared`.
+ EOT
+
+ validation {
+ condition = contains(["Dev", "Test", "Prod", "Shared"], var.stage)
+ error_message = "Stage must be one of the following: `Dev`, `Test`, `Prod`, `Shared`."
+ }
+}
diff --git a/sample-setups/modules/sap-btp-subaccount-default-entitlements/versions.tf b/sample-setups/modules/sap-btp-subaccount-default-entitlements/versions.tf
new file mode 100644
index 0000000..2dc2c98
--- /dev/null
+++ b/sample-setups/modules/sap-btp-subaccount-default-entitlements/versions.tf
@@ -0,0 +1,3 @@
+terraform {
+ required_version = ">= 1.11"
+}