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
26 changes: 17 additions & 9 deletions released/discovery_center/mission_4371/step1/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Discovery Center Mission: Develop a CAP-based (multitenant) application using GenAI and RAG (4371)
# Discovery Center Mission: Develop a CAP-based (multitenant) application using GenAI and RAG (4371) - Step 1

## Overview

Expand All @@ -18,27 +18,35 @@ The setup comprises the following resources:

To deploy the resources you must:

1. Export environment variables BTP_USERNAME, BTP_PASSWORD, CF_USER, and CF_PASSWORD with your username and password for the custom IdP of your global account.
1. Set your credentials as environment variables

```bash
export BTP_USERNAME ='<Email address of your BTP user>'
export BTP_PASSWORD ='<Password of your BTP user>'
export CF_USER ='<Email address of your BTP user>'
export CF_PASSWORD ='<Password of your BTP user>'
```

2. Change the variables in the `sample.tfvars` file in the main folder to meet your requirements

2. Change the variables in the `samples.tfvars` file in the main folder to meet your requirements
> The minimal set of parameters you should specify (besides user_email and password) is global account (i.e. its subdomain) and the used custom_idp and all user assignments

> ⚠ NOTE: You should pay attention **specifically** to the users defined in the samples.tfvars whether they already exist in your SAP BTP accounts. Otherwise you might get error messages like e.g. `Error: The user could not be found: [email protected]`.
> ⚠ NOTE: You should pay attention **specifically** to the users defined in the sample.tfvars whether they already exist in your SAP BTP accounts. Otherwise, you might get error messages like, e.g., `Error: The user could not be found: [email protected]`.

3. Execute the apply.sh script.

4. Verify e.g., in BTP cockpit that a new subaccount with a integration suite, SAP Business Application Studio, CF environment instance and a CF space have been created.
3. Initialize your workspace:

```bash
terraform init
```

5. You can check what Terraform plans to apply based on your configuration:
4. You can check what Terraform plans to apply based on your configuration:

```bash
terraform plan -var-file="sample.tfvars"
```

6. Apply your configuration to provision the resources:
5. Apply your configuration to provision the resources:

```bash
terraform apply -var-file="sample.tfvars"
Expand All @@ -50,4 +58,4 @@ You probably want to remove the assets after trying them out to avoid unnecessar

```bash
terraform destroy -var-file="sample.tfvars"
```
```
75 changes: 72 additions & 3 deletions released/discovery_center/mission_4371/step1/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,30 @@ resource "btp_subaccount" "dc_mission" {
usage = "USED_FOR_PRODUCTION"
}

# ------------------------------------------------------------------------------------------------------
# Assign custom IDP to sub account (if custom_idp is set)
# ------------------------------------------------------------------------------------------------------
resource "btp_subaccount_trust_configuration" "fully_customized" {
# Only create trust configuration if custom_idp has been set
count = var.custom_idp == "" ? 0 : 1
subaccount_id = btp_subaccount.dc_mission.id
identity_provider = var.custom_idp
}

locals {
custom_idp_tenant = var.custom_idp != "" ? element(split(".", var.custom_idp), 0) : ""
origin_key = local.custom_idp_tenant != "" ? "${local.custom_idp_tenant}-platform" : "sap.default"
origin_key_app_users = var.custom_idp != "" ? var.custom_idp_apps_origin_key : "sap.default"
}

# ------------------------------------------------------------------------------------------------------
# Assignment of users as sub account administrators
# ------------------------------------------------------------------------------------------------------
resource "btp_subaccount_role_collection_assignment" "subaccount-admins" {
for_each = toset(var.subaccount_admins)
subaccount_id = btp_subaccount.dc_mission.id
role_collection_name = "Subaccount Administrator"
origin = local.origin_key
user_name = each.value
}
# ------------------------------------------------------------------------------------------------------
Expand All @@ -35,6 +52,7 @@ resource "btp_subaccount_role_collection_assignment" "subaccount-service-admins"
for_each = toset(var.subaccount_service_admins)
subaccount_id = btp_subaccount.dc_mission.id
role_collection_name = "Subaccount Service Administrator"
origin = local.origin_key
user_name = each.value
}

Expand Down Expand Up @@ -76,6 +94,56 @@ resource "btp_subaccount_service_binding" "ai_core_binding" {
name = "ai-core-key"
}

# ------------------------------------------------------------------------------------------------------
# Setup destination
# ------------------------------------------------------------------------------------------------------
# Entitle
resource "btp_subaccount_entitlement" "destination" {
subaccount_id = btp_subaccount.dc_mission.id
service_name = "destination"
plan_name = "lite"
}

data "btp_subaccount_service_plan" "destination" {
subaccount_id = btp_subaccount.dc_mission.id
offering_name = "destination"
name = "lite"
depends_on = [btp_subaccount_entitlement.destination]
}

# Create service instance
resource "btp_subaccount_service_instance" "destination" {
subaccount_id = btp_subaccount.dc_mission.id
serviceplan_id = data.btp_subaccount_service_plan.destination.id
name = "destination"
depends_on = [btp_subaccount_service_binding.ai_core_binding, data.btp_subaccount_service_plan.destination]
parameters = jsonencode({
HTML5Runtime_enabled = true
init_data = {
subaccount = {
existing_destinations_policy = "update"
destinations = [
# This is the destination to the ai-core binding
{
Description = "[Do not delete] PROVIDER_AI_CORE_DESTINATION_HUB"
Type = "HTTP"
clientId = "${jsondecode(btp_subaccount_service_binding.ai_core_binding.credentials)["clientid"]}"
clientSecret = "${jsondecode(btp_subaccount_service_binding.ai_core_binding.credentials)["clientsecret"]}"
"HTML5.DynamicDestination" = true
"HTML5.Timeout" = 5000
Authentication = "OAuth2ClientCredentials"
Name = "PROVIDER_AI_CORE_DESTINATION_HUB"
tokenServiceURL = "${jsondecode(btp_subaccount_service_binding.ai_core_binding.credentials)["url"]}/oauth/token"
ProxyType = "Internet"
URL = "${jsondecode(btp_subaccount_service_binding.ai_core_binding.credentials)["serviceurls"]["AI_API_URL"]}/v2"
tokenServiceURLType = "Dedicated"
}
]
}
}
})
}


# ------------------------------------------------------------------------------------------------------
# Entitle subaccount for usage of SAP HANA Cloud tools
Expand All @@ -95,11 +163,11 @@ resource "btp_subaccount_subscription" "hana_cloud_tools" {

# Assign users to Role Collection: SAP HANA Cloud Administrator
resource "btp_subaccount_role_collection_assignment" "hana_cloud_admin" {
for_each = toset(var.hana_cloud_admins)
subaccount_id = btp_subaccount.dc_mission.id
role_collection_name = "SAP HANA Cloud Administrator"
user_name = each.value
user_name = var.hana_system_admin
depends_on = [btp_subaccount_subscription.hana_cloud_tools]
origin = local.origin_key_app_users
}

# ------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -197,10 +265,11 @@ resource "btp_subaccount_environment_instance" "cloudfoundry" {
resource "local_file" "output_vars_step1" {
count = var.create_tfvars_file_for_step2 ? 1 : 0
content = <<-EOT
globalaccount = "${var.globalaccount}"
subaccount_id = "${btp_subaccount.dc_mission.id}"
cf_api_url = "${jsondecode(btp_subaccount_environment_instance.cloudfoundry.labels)["API Endpoint"]}"
cf_org_id = "${jsondecode(btp_subaccount_environment_instance.cloudfoundry.labels)["Org ID"]}"
origin = "${var.origin}"
custom_idp = ${jsonencode(var.custom_idp)}
cf_space_name = "${var.cf_space_name}"
cf_org_admins = ${jsonencode(var.cf_org_admins)}
cf_org_users = ${jsonencode(var.cf_org_users)}
Expand Down
4 changes: 4 additions & 0 deletions released/discovery_center/mission_4371/step1/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ output "cf_org_id" {
value = jsondecode(btp_subaccount_environment_instance.cloudfoundry.labels)["Org ID"]
description = "The Cloudfoundry org id."
}

output "hana_cloud_tools_url" {
value = btp_subaccount_subscription.hana_cloud_tools.subscription_url
}
2 changes: 1 addition & 1 deletion released/discovery_center/mission_4371/step1/provider.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ terraform {
required_providers {
btp = {
source = "sap/btp"
version = "~> 1.5.0"
version = "~> 1.6.0"
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions released/discovery_center/mission_4371/step1/samples.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
globalaccount = "yourglobalaccount"
region = "us10"
subaccount_name = "SAP Discovery Center Mission 4371"
custom_idp = "sap.ids"
custom_idp = "<your_idp>.accounts.ondemand.com"

# ------------------------------------------------------------------------------------------------------
# Project specific configuration (please adapt!)
Expand All @@ -15,7 +15,7 @@ custom_idp = "sap.ids"
subaccount_admins = ["[email protected]"]
subaccount_service_admins = ["[email protected]"]

hana_cloud_admins = ["[email protected]"]
hana_system_admin = "[email protected]"
hana_system_password = "Abc12345"

# Don't add the user, that is executing the TF script to cf_org_admins or cf_org_users!
Expand Down
107 changes: 32 additions & 75 deletions released/discovery_center/mission_4371/step1/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,39 @@ variable "cli_server_url" {
default = "https://cli.btp.cloud.sap"
}

variable "custom_idp" {
type = string
description = "The custom identity provider for the subaccount."
default = ""
}

variable "custom_idp_apps_origin_key" {
type = string
description = "The custom identity provider for the subaccount."
default = "sap.custom"
}

variable "origin" {
type = string
description = "Defines the origin key of the identity provider"
default = "sap.ids"
# The value for the origin_key can be defined
# but are normally set to "sap.ids", "sap.default" or "sap.custom"
}

variable "origin_key" {
type = string
description = "Defines the origin key of the identity provider"
default = ""
# The value for the origin_key can be defined, set to "sap.ids", "sap.default" or "sap.custom"
}


# subaccount
variable "subaccount_name" {
type = string
description = "The subaccount name."
default = "SAP Discovery Center Mission 3774 - Central Inbox with SAP Task Center"
default = "SAP Discovery Center Mission 4371"
}
variable "subaccount_id" {
type = string
Expand All @@ -28,25 +56,11 @@ variable "subaccount_id" {
variable "subaccount_admins" {
type = list(string)
description = "Defines the colleagues who are added to each subaccount as subaccount administrators."
default = ["[email protected]", "[email protected]"]

# add validation to check if admins contains a list of valid email addresses
validation {
condition = length([for email in var.subaccount_admins : can(regex("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", email))]) == length(var.subaccount_admins)
error_message = "Please enter a valid email address for the CF space managers."
}
}

variable "subaccount_service_admins" {
type = list(string)
description = "Defines the colleagues who are added to each subaccount as subaccount service administrators."
default = ["[email protected]", "[email protected]"]

# add validation to check if admins contains a list of valid email addresses
validation {
condition = length([for email in var.subaccount_service_admins : can(regex("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", email))]) == length(var.subaccount_service_admins)
error_message = "Please enter a valid email address for the CF space managers."
}
}

variable "region" {
Expand All @@ -63,28 +77,16 @@ variable "region" {
}


variable "hana_cloud_admins" {
type = list(string)
variable "hana_system_admin" {
type = string
description = "Defines the colleagues who are added as admins to access the instance of SAP HANA Cloud."
default = ["[email protected]", "[email protected]"]

# add validation to check if admins contains a list of valid email addresses
validation {
condition = length([for email in var.hana_cloud_admins : can(regex("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", email))]) == length(var.hana_cloud_admins)
error_message = "Please enter a valid email address for the admins of SAP HANA Cloud instance."
}
}

variable "custom_idp" {
type = string
description = "Defines the custom IdP"
default = ""
}

variable "create_tfvars_file_for_step2" {
type = bool
description = "Switch to enable the creation of the tfvars file for step 2."
default = false
default = true
}

variable "ai_core_plan_name" {
Expand Down Expand Up @@ -127,19 +129,6 @@ variable "hana_system_password" {
}
}

variable "target_ai_core_model" {
type = list(any)
description = "Defines the target AI core model to be used by the AI Core service"
default = ["gpt-35-turbo"]

validation {
condition = length([
for o in var.target_ai_core_model : true
if contains(["gpt-35-turbo", "gpt-35-turbo-0125", "gpt-35-turbo-16k", "gpt-4", "gpt-4-32k", "text-embedding-ada-002", "gemini-1.0-pro", "text-bison", "chat-bison", "textembedding-gecko-multilingual", "textembedding-gecko", "tiiuae--falcon-40b-instruct"], o)
]) == length(var.target_ai_core_model)
error_message = "Please enter a valid entry for the target_ai_core_model of the AI Core service. Valid values are: gpt-35-turbo, gpt-35-turbo-16k, gpt-4, gpt-4-32k, text-embedding-ada-002, tiiuae--falcon-40b-instruct."
}
}

variable "cf_landscape_label" {
type = string
Expand All @@ -162,53 +151,21 @@ variable "cf_space_name" {
variable "cf_space_developers" {
type = list(string)
description = "CF Space developers"
default = ["[email protected]", "[email protected]"]
# add validation to check if CF Space developers contains a list of valid email addresses
validation {
condition = length([for email in var.cf_space_developers : can(regex("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", email))]) == length(var.cf_space_developers)
error_message = "Please enter a valid email address for the CF Space developers."
}
}

variable "cf_space_managers" {
type = list(string)
description = "CF Space managers"
default = ["[email protected]", "[email protected]"]
# add validation to check if CF Space managers contains a list of valid email addresses
validation {
condition = length([for email in var.cf_space_managers : can(regex("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", email))]) == length(var.cf_space_managers)
error_message = "Please enter a valid email address for the Cloud Connector Administrators."
}
}

variable "cf_org_admins" {
type = list(string)
description = "CF Org Admins"
default = ["[email protected]", "[email protected]"]
# add validation to check if CF Org Admins contains a list of valid email addresses
validation {
condition = length([for email in var.cf_org_admins : can(regex("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", email))]) == length(var.cf_org_admins)
error_message = "Please enter a valid email address for the CF Org Admins."
}
}

variable "cf_org_users" {
type = list(string)
description = "CF Org Users"
default = ["[email protected]", "[email protected]"]
# add validation to check if CF Org Users contains a list of valid email addresses
validation {
condition = length([for email in var.cf_org_users : can(regex("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", email))]) == length(var.cf_org_users)
error_message = "Please enter a valid email address for the CF Org Users."
}
}

variable "origin" {
type = string
description = "Defines the origin key of the identity provider"
default = "sap.ids"
# The value for the origin_key can be defined
# but are normally set to "sap.ids", "sap.default" or "sap.custom"
}

variable "cf_org_name" {
Expand Down
Loading