Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 91 additions & 0 deletions released/btp-usability-days/2025/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# Sample for SAP BTP Usability Days 2025

This folder contains a sample setup of a subaccount on SAP BTP using the Terraform provider for SAP BTP.

> [!IMPORTANT]
> The sample is tested agianst a SAP BTP CPEA/BTPEA account. The configuration will not work when using a SAP BTP trial account.

## Prerequisites

Before you apply the configuration, make sure you have entered the necessary variables in the `samples.tfvars` file:

```terraform
globalaccount = "<YOUR GLOBAL ACCOUNT SUBDOMAIN>"
cost_center = "CC-12345678"
contact_person = "John Doe"
department = "Sales"
```

If you use a custom platform IdP, make sure taht you also add the `idp` variable to the `samples.tfvars` file.

For the authentication to SAP BTP we recommend using the environment variables `BTP_USERNAME` and `BTP_PASSWORD` to store your credentials securely.

On Windows, you can set them in PowerShell like this:

```powershell
$env:BTP_USERNAME="your-username"
$env:BTP_PASSWORD="your-password"
```

On Linux or Mac OS, you can set them in the terminal like this:

```bash
export BTP_USERNAME="your-username"
export BTP_PASSWORD="your-password"
```

## Execution

To execute the configuration, run the following commands in your terminal:

1. Initialize the Terraform working directory:
```bash
terraform init
```
2. Validate the configuration:
```bash
terraform validate
```

3. Create and review the execution plan:
```bash
terraform plan -var-file="samples.tfvars" -out="plan.out"
```

4. If the proposed changes are as expected, apply the execution plan:

```bash
terraform apply "plan.out"
```

Once the apply is complete, you can find the outputs in the terminal or by running:

```bash
terraform output
```

The output `subaccount_url` provides a direct link to the created subaccount in the SAP BTP Cockpit.


## Cleanup

To remove the created resources and clean up your environment, run the following command:

```bash
terraform destroy -var-file="samples.tfvars"
```

Review the proposed plan and confirm the destruction of resources when prompted.


## Content

The configuration showcases some specific features:

- Validation of input variables using `validation` blocks in the `variables.tf` file.
- Implementing naming conventions
- Using maps and objects and the `lookup()` function to retrieve values based on the variables
- Using ternary operators for conditionally setting values resouce attributes
- Using modules as reusable components
- Creating multiple resources using `for_each` based on a list
- Creating outputs with dynamic values
132 changes: 132 additions & 0 deletions released/btp-usability-days/2025/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Needed for subdomain uniqueness
resource "random_uuid" "self" {}

# Needed for output to construct the subaccount URL
data "btp_globalaccount" "self" {}

locals {
# Define a mapping of regions to their respective geo regions
region_mapping = {
"br10" = "LATAM"
"jp10" = "APAC"
"ap10" = "APAC"
"ap11" = "APAC"
"ap12" = "APAC"
"ca10" = "AMER"
"eu10" = "EMEA"
"eu11" = "EMEA"
"us10" = "AMER"
"us11" = "AMER"
"us30" = "AMER"
"eu30" = "EMEA"
"in30" = "APAC"
"il30" = "EMEA"
"jp30" = "APAC"
"jp31" = "APAC"
"ap30" = "APAC"
"br30" = "APAC"
"eu20" = "EMEA"
"ap20" = "APAC"
"ap21" = "APAC"
"br20" = "APAC"
"ca20" = "AMER"
"cn20" = "APAC"
"us20" = "AMER"
"jp20" = "APAC"
"us21" = "AMER"
"ch20" = "EMEA"
}

# Define default entitlements per stage
default_entitlements = {
"Dev" = {
"aicore" = ["standard"],
"ai-launchpad" = ["standard"]
"alert-notification" = ["standard"],
"application-logs" = ["standard=1"],
"build-workzone-standard" = ["standard"],
"credstore" = ["standard=1"],
"jobscheduler" = ["standard=1"],
"hana-cloud" = ["hana"],
"transport" = ["standard"],
},
"Test" = {
"ai-launchpad" = ["standard"]
"alert-notification" = ["standard"],
"application-logs" = ["standard=1"],
"build-workzone-standard" = ["standard"],
"credstore" = ["standard=1"],
"jobscheduler" = ["standard=1"],
"hana-cloud" = ["hana"],
"transport" = ["standard"],
},
"Prod" = {
"ai-launchpad" = ["standard"]
"alert-notification" = ["standard"],
"application-logs" = ["standard=1"],
"build-workzone-standard" = ["standard"],
"credstore" = ["standard=1"],
"jobscheduler" = ["standard=1"],
"hana-cloud" = ["hana"],
"transport" = ["standard"],
}
}

# Naming conventions
subaccount_name = "${var.subaccount_name} ${var.stage}"
subaccount_subdomain = "${replace(lower(var.subaccount_name), " ", "-")}-${lower(var.stage)}-${random_uuid.self.result}"
subaccount_description = "Subaccount ${var.subaccount_name} in the ${var.stage} stage for ${var.department}."
cf_org_name = "CF-${var.subaccount_name}-${var.stage}"
}

resource "btp_subaccount" "self" {
name = local.subaccount_name
subdomain = local.subaccount_subdomain
region = var.region
description = local.subaccount_description
usage = var.stage == "Prod" ? "USED_FOR_PRODUCTION" : "NOT_USED_FOR_PRODUCTION"
beta_enabled = var.stage == "Dev" ? true : false
labels = {
"Cost Center" = ["${var.cost_center}"]
"Contact Person" = ["${var.contact_person}"]
"Department" = ["${var.department}"]
"Region" = ["${lookup(local.region_mapping, var.region, "UNKNOWN")}"]
}
}

module "sap_btp_entitlements" {
source = "aydin-ozcan/sap-btp-entitlements/btp"
version = "~> 1.0.1"

subaccount = btp_subaccount.self.id
entitlements = local.default_entitlements[var.stage]
}

data "btp_subaccount_environments" "all" {
subaccount_id = btp_subaccount.self.id
}

resource "terraform_data" "cf_landscape_label" {
input = [for env in data.btp_subaccount_environments.all.values : env if env.service_name == "cloudfoundry" && env.environment_type == "cloudfoundry"][0].landscape_label
}


resource "btp_subaccount_environment_instance" "cloudfoundry" {
subaccount_id = btp_subaccount.self.id
name = local.cf_org_name
environment_type = "cloudfoundry"
service_name = "cloudfoundry"
plan_name = "standard"
landscape_label = terraform_data.cf_landscape_label.output
parameters = jsonencode({
instance_name = local.subaccount_subdomain
})
}

resource "btp_subaccount_role_collection_assignment" "emergency_admins" {
for_each = toset(var.emergency_subaccount_admins)

subaccount_id = btp_subaccount.self.id
role_collection_name = "Subaccount Administrator"
user_name = each.value
}
9 changes: 9 additions & 0 deletions released/btp-usability-days/2025/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
output "subaccount_url" {
value = "https://emea.cockpit.btp.cloud.sap/cockpit/#globalaccount/${data.btp_globalaccount.self.id}/subaccount/${btp_subaccount.self.id}"
description = "The SAP BTP subaccount URL"
}

output "cf_api_url" {
value = jsondecode(btp_subaccount_environment_instance.cloudfoundry.labels)["API Endpoint"]
description = "The Cloud Foundry API URL"
}
14 changes: 14 additions & 0 deletions released/btp-usability-days/2025/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
terraform {
required_providers {
btp = {
source = "SAP/btp"
version = "~> 1.15.0"
}
}
}

# Configure the BTP Provider
provider "btp" {
globalaccount = var.globalaccount
idp = var.idp
}
7 changes: 7 additions & 0 deletions released/btp-usability-days/2025/samples.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
globalaccount = "<YOUR_GLOBAL_ACCOUNT_SUBDOMAIN>"
subaccount_name = "btp-usability-days"
region = "us10"
cost_center = "CC-12345678"
contact_person = "John Doe"
department = "Sales"
emergency_subaccount_admins = ["[email protected]", "firefighter1"]
52 changes: 52 additions & 0 deletions released/btp-usability-days/2025/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
variable "globalaccount" {
description = "The BTP global account name"
type = string
}

variable "idp" {
description = "The Identity Provider to use for authentication (e.g. 'ias' or 'xsuaa')"
type = string
default = null
}

variable "subaccount_name" {
description = "The BTP subaccount name"
type = string
}

variable "region" {
description = "The region of the SAP BTP subaccount"
type = string
default = "us10"
}

variable "stage" {
description = "The stage of the SAP BTP subaccount"
type = string
default = "Dev"
validation {
condition = contains(["Dev", "Test", "Prod"], var.stage)
error_message = "Stage must be one of the following: `Dev`, `Test`, `Prod`."
}
}

variable "cost_center" {
description = "The cost center for the SAP BTP subaccount"
type = string
}

variable "contact_person" {
description = "The contact person for the SAP BTP subaccount"
type = string
}

variable "department" {
description = "The department for the SAP BTP subaccount"
type = string
}

variable "emergency_subaccount_admins" {
description = "List of emergency subaccount admins (emails)"
type = list(string)
default = []
}