diff --git a/released/discovery_center/mission_4356/apply.sh b/released/discovery_center/mission_4356/apply.sh deleted file mode 100755 index fb333585..00000000 --- a/released/discovery_center/mission_4356/apply.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -cd step1 - -terraform init -terraform apply -var-file='../samples.tfvars' -auto-approve -terraform output > ../step2/step1vars.tfvars - -cd ../step2 - -terraform init -terraform apply -var-file=step1vars.tfvars -var-file='../samples.tfvars' -auto-approve - -cd .. \ No newline at end of file diff --git a/released/discovery_center/mission_4356/destroy.sh b/released/discovery_center/mission_4356/destroy.sh deleted file mode 100755 index 549e1c4e..00000000 --- a/released/discovery_center/mission_4356/destroy.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh - -cd step-2 - -terraform destroy -var-file=step1vars.tfvars -var-file='../samples.tfvars' -auto-approve -rm samples.tfvars - -cd ../step-1 - -terraform destroy -var-file='../samples.tfvars' -auto-approve - -cd .. \ No newline at end of file diff --git a/released/discovery_center/mission_4356/samples.tfvars b/released/discovery_center/mission_4356/samples.tfvars deleted file mode 100644 index 43b5f802..00000000 --- a/released/discovery_center/mission_4356/samples.tfvars +++ /dev/null @@ -1,18 +0,0 @@ -globalaccount = "ticoo" -region = "us10" -subaccount_name = "Discovery Center mission - Deliver Connected Experiences with a single view of Material Availability" -cf_org_name = "cf-environment" - -subaccount_admins = ["m.palavalli1@sap.com"] -subaccount_service_admins = ["m.palavalli1@sap.com"] - -appstudio_developers = ["m.palavalli@sap.com", "m.palavalli1@sap.com"] -appstudio_admin = ["m.palavalli@sap.com", "m.palavalli1@sap.com"] -cloudconnector_admin = ["m.palavalli@sap.com", "m.palavalli1@sap.com"] -conn_dest_admin = ["m.palavalli@sap.com", "m.palavalli1@sap.com"] -int_provisioner = ["m.palavalli@sap.com", "m.palavalli1@sap.com"] - -cf_space_developers = ["m.palavalli1@sap.com"] -cf_space_managers = ["m.palavalli1@sap.com"] -cf_org_admins = ["m.palavalli1@sap.com"] -cf_org_users = ["m.palavalli1@sap.com"] diff --git a/released/discovery_center/mission_4356/README.md b/released/discovery_center/mission_4356/step1/README.md similarity index 100% rename from released/discovery_center/mission_4356/README.md rename to released/discovery_center/mission_4356/step1/README.md diff --git a/released/discovery_center/mission_4356/step1/main.tf b/released/discovery_center/mission_4356/step1/main.tf index 5facadde..5ced3fc3 100644 --- a/released/discovery_center/mission_4356/step1/main.tf +++ b/released/discovery_center/mission_4356/step1/main.tf @@ -1,109 +1,110 @@ -############################################################################################### +# ------------------------------------------------------------------------------------------------------ # Setup of names in accordance to naming convention -############################################################################################### +# ------------------------------------------------------------------------------------------------------ resource "random_uuid" "uuid" {} locals { - random_uuid = random_uuid.uuid.result - project_subaccount_domain = lower(replace("mission-4172-${local.random_uuid}", "_", "-")) - project_subaccount_cf_org = substr(replace("${local.project_subaccount_domain}", "-", ""), 0, 32) + random_uuid = random_uuid.uuid.result + subaccount_domain = lower(replace("mission-4356-${local.random_uuid}", "_", "-")) + # If a cf_org_name was defined by the user, take that as a subaccount_cf_org. Otherwise create it. + subaccount_cf_org = length(var.cf_org_name) > 0 ? var.cf_org_name : substr(replace("${local.subaccount_domain}", "-", ""), 0, 32) } -############################################################################################### +# ------------------------------------------------------------------------------------------------------ # Creation of subaccount -############################################################################################### -resource "btp_subaccount" "project" { +# ------------------------------------------------------------------------------------------------------ +resource "btp_subaccount" "dc_mission" { count = var.subaccount_id == "" ? 1 : 0 name = var.subaccount_name - subdomain = local.project_subaccount_domain + subdomain = local.subaccount_domain region = lower(var.region) usage = "USED_FOR_PRODUCTION" } -data "btp_subaccount" "project" { - id = var.subaccount_id != "" ? var.subaccount_id : btp_subaccount.project[0].id +data "btp_subaccount" "dc_mission" { + id = var.subaccount_id != "" ? var.subaccount_id : btp_subaccount.dc_mission[0].id } -############################################################################################### +# ------------------------------------------------------------------------------------------------------ # Assignment of users as sub account administrators -############################################################################################### +# ------------------------------------------------------------------------------------------------------ resource "btp_subaccount_role_collection_assignment" "subaccount-admins" { - for_each = toset("${var.subaccount_admins}") - subaccount_id = data.btp_subaccount.project.id + for_each = toset(var.subaccount_admins) + subaccount_id = data.btp_subaccount.dc_mission.id role_collection_name = "Subaccount Administrator" user_name = each.value } -############################################################################################### +# ------------------------------------------------------------------------------------------------------ # Assignment of users as sub account service administrators -############################################################################################### +# ------------------------------------------------------------------------------------------------------ resource "btp_subaccount_role_collection_assignment" "subaccount-service-admins" { - for_each = toset("${var.subaccount_service_admins}") - subaccount_id = data.btp_subaccount.project.id + for_each = toset(var.subaccount_service_admins) + subaccount_id = data.btp_subaccount.dc_mission.id role_collection_name = "Subaccount Service Administrator" user_name = each.value } -###################################################################### -# Extract list of CF landscape labels from environments -###################################################################### +# ------------------------------------------------------------------------------------------------------ +# CLOUDFOUNDRY PREPARATION +# ------------------------------------------------------------------------------------------------------ +# +# Fetch all available environments for the subaccount data "btp_subaccount_environments" "all" { - subaccount_id = data.btp_subaccount.project.id + subaccount_id = data.btp_subaccount.dc_mission.id } - -locals { - cf_landscape_labels = [ - for env in data.btp_subaccount_environments.all.values : env.landscape_label - if env.environment_type == "cloudfoundry" - ] +# ------------------------------------------------------------------------------------------------------ +# Take the landscape label from the first CF environment if no environment label is provided +# ------------------------------------------------------------------------------------------------------ +resource "terraform_data" "cf_landscape_label" { + input = length(var.cf_landscape_label) > 0 ? var.cf_landscape_label : [for env in data.btp_subaccount_environments.all.values : env if env.service_name == "cloudfoundry" && env.environment_type == "cloudfoundry"][0].landscape_label } - -###################################################################### +# ------------------------------------------------------------------------------------------------------ # Creation of Cloud Foundry environment -###################################################################### +# ------------------------------------------------------------------------------------------------------ resource "btp_subaccount_environment_instance" "cloudfoundry" { - subaccount_id = data.btp_subaccount.project.id - name = var.cf_org_name + subaccount_id = data.btp_subaccount.dc_mission.id + name = local.subaccount_cf_org environment_type = "cloudfoundry" service_name = "cloudfoundry" plan_name = "standard" - landscape_label = local.cf_landscape_labels[0] + landscape_label = terraform_data.cf_landscape_label.output parameters = jsonencode({ - instance_name = local.project_subaccount_cf_org + instance_name = local.subaccount_cf_org }) } -###################################################################### +# ------------------------------------------------------------------------------------------------------ # Entitlement of all general services -###################################################################### +# ------------------------------------------------------------------------------------------------------ resource "btp_subaccount_entitlement" "genentitlements" { for_each = { for index, entitlement in var.entitlements : index => entitlement } - subaccount_id = data.btp_subaccount.project.id + subaccount_id = data.btp_subaccount.dc_mission.id service_name = each.value.service_name plan_name = each.value.plan_name } -###################################################################### +# ------------------------------------------------------------------------------------------------------ # Create app subscription to SAP Integration Suite -###################################################################### +# ------------------------------------------------------------------------------------------------------ resource "btp_subaccount_entitlement" "sap_integration_suite" { - subaccount_id = data.btp_subaccount.project.id + subaccount_id = data.btp_subaccount.dc_mission.id service_name = local.service_name__sap_integration_suite plan_name = var.service_plan__sap_integration_suite } data "btp_subaccount_subscriptions" "all" { - subaccount_id = data.btp_subaccount.project.id + subaccount_id = data.btp_subaccount.dc_mission.id depends_on = [btp_subaccount_entitlement.sap_integration_suite] } resource "btp_subaccount_subscription" "sap_integration_suite" { - subaccount_id = data.btp_subaccount.project.id + subaccount_id = data.btp_subaccount.dc_mission.id app_name = [ for subscription in data.btp_subaccount_subscriptions.all.values : subscription @@ -115,25 +116,24 @@ resource "btp_subaccount_subscription" "sap_integration_suite" { resource "btp_subaccount_role_collection_assignment" "int_prov" { depends_on = [btp_subaccount_subscription.sap_integration_suite] - for_each = toset(var.int_provisioner) - subaccount_id = data.btp_subaccount.project.id + for_each = toset(var.int_provisioners) + subaccount_id = data.btp_subaccount.dc_mission.id role_collection_name = "Integration_Provisioner" user_name = each.value } -# ###################################################################### -# # Create app subscription to SAP Business APplication Studio -# ###################################################################### - +# ------------------------------------------------------------------------------------------------------ +# Create app subscription to SAP Business Application Studio +# ------------------------------------------------------------------------------------------------------ resource "btp_subaccount_entitlement" "bas" { - subaccount_id = data.btp_subaccount.project.id + subaccount_id = data.btp_subaccount.dc_mission.id service_name = local.service__sap_business_app_studio plan_name = var.service_plan__sap_business_app_studio } # Create app subscription to busineass applicaiton stuido resource "btp_subaccount_subscription" "bas" { - subaccount_id = data.btp_subaccount.project.id + subaccount_id = data.btp_subaccount.dc_mission.id app_name = local.service__sap_business_app_studio plan_name = var.service_plan__sap_business_app_studio depends_on = [btp_subaccount_entitlement.bas] @@ -142,35 +142,64 @@ resource "btp_subaccount_subscription" "bas" { resource "btp_subaccount_role_collection_assignment" "bas_dev" { depends_on = [btp_subaccount_subscription.bas] for_each = toset(var.appstudio_developers) - subaccount_id = data.btp_subaccount.project.id + subaccount_id = data.btp_subaccount.dc_mission.id role_collection_name = "Business_Application_Studio_Developer" user_name = each.value } resource "btp_subaccount_role_collection_assignment" "bas_admn" { depends_on = [btp_subaccount_subscription.bas] - for_each = toset(var.appstudio_admin) - subaccount_id = data.btp_subaccount.project.id + for_each = toset(var.appstudio_admins) + subaccount_id = data.btp_subaccount.dc_mission.id role_collection_name = "Business_Application_Studio_Administrator" user_name = each.value } -###################################################################### +# ------------------------------------------------------------------------------------------------------ # Assign Role Collection -###################################################################### +# ------------------------------------------------------------------------------------------------------ resource "btp_subaccount_role_collection_assignment" "cloud_conn_admn" { depends_on = [btp_subaccount_entitlement.genentitlements] - for_each = toset(var.cloudconnector_admin) - subaccount_id = data.btp_subaccount.project.id + for_each = toset(var.cloudconnector_admins) + subaccount_id = data.btp_subaccount.dc_mission.id role_collection_name = "Cloud Connector Administrator" user_name = each.value } resource "btp_subaccount_role_collection_assignment" "conn_dest_admn" { depends_on = [btp_subaccount_entitlement.genentitlements] - for_each = toset(var.conn_dest_admin) - subaccount_id = data.btp_subaccount.project.id + for_each = toset(var.conn_dest_admins) + subaccount_id = data.btp_subaccount.dc_mission.id role_collection_name = "Connectivity and Destination Administrator" user_name = each.value } + + +# ------------------------------------------------------------------------------------------------------ +# Create tfvars file for step 2 (if variable `create_tfvars_file_for_step2` is set to true) +# ------------------------------------------------------------------------------------------------------ +resource "local_file" "output_vars_step1" { + count = var.create_tfvars_file_for_step2 ? 1 : 0 + content = <<-EOT + globalaccount = "${var.globalaccount}" + cli_server_url = ${jsonencode(var.cli_server_url)} + + subaccount_id = "${data.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}" + + cf_space_name = "${var.cf_space_name}" + + cf_org_admins = ${jsonencode(var.cf_org_admins)} + cf_org_users = ${jsonencode(var.cf_org_users)} + cf_space_developers = ${jsonencode(var.cf_space_developers)} + cf_space_managers = ${jsonencode(var.cf_space_managers)} + + EOT + filename = "../step2/terraform.tfvars" +} diff --git a/released/discovery_center/mission_4356/step1/output.tf b/released/discovery_center/mission_4356/step1/output.tf index 56f90f7b..dcd4715b 100644 --- a/released/discovery_center/mission_4356/step1/output.tf +++ b/released/discovery_center/mission_4356/step1/output.tf @@ -1,15 +1,49 @@ -output "cf_landscape_label" { - value = btp_subaccount_environment_instance.cloudfoundry.landscape_label +output "subaccount_id" { + value = data.btp_subaccount.dc_mission.id + description = "The ID of the subaccount." } output "cf_api_url" { - value = jsondecode(btp_subaccount_environment_instance.cloudfoundry.labels)["API Endpoint"] + value = jsondecode(btp_subaccount_environment_instance.cloudfoundry.labels)["API Endpoint"] + description = "The Cloudfoundry API endpoint." +} + +output "cf_landscape_label" { + value = terraform_data.cf_landscape_label.output + description = "The Cloudfoundry landscape label." } output "cf_org_id" { - value = btp_subaccount_environment_instance.cloudfoundry.platform_id + value = jsondecode(btp_subaccount_environment_instance.cloudfoundry.labels)["Org ID"] + description = "The Cloudfoundry org id." } -output "subaccount_id" { - value = data.btp_subaccount.project.id -} \ No newline at end of file +output "cf_org_name" { + value = jsondecode(btp_subaccount_environment_instance.cloudfoundry.labels)["Org Name"] + description = "The Cloudfoundry org name." +} + +output "cf_space_name" { + value = var.cf_space_name + description = "The name of the Cloud Foundry space." +} + +output "cf_org_admins" { + value = var.cf_org_admins + description = "List of users to set as Cloudfoundry org administrators." +} + +output "cf_space_developers" { + value = var.cf_space_developers + description = "List of users to set as Cloudfoundry space developers." +} + +output "cf_space_managers" { + value = var.cf_space_managers + description = "List of users to set as Cloudfoundry space managers." +} + +output "origin" { + value = var.origin + description = "The identity provider for the UAA user." +} \ No newline at end of file diff --git a/released/discovery_center/mission_4356/step1/provider.tf b/released/discovery_center/mission_4356/step1/provider.tf index f4e6f577..f80eefad 100644 --- a/released/discovery_center/mission_4356/step1/provider.tf +++ b/released/discovery_center/mission_4356/step1/provider.tf @@ -1,7 +1,7 @@ terraform { required_providers { btp = { - source = "SAP/btp" + source = "sap/btp" version = "1.4.0" } } diff --git a/released/discovery_center/mission_4356/step1/sample.tfvars b/released/discovery_center/mission_4356/step1/sample.tfvars new file mode 100644 index 00000000..e7e94f97 --- /dev/null +++ b/released/discovery_center/mission_4356/step1/sample.tfvars @@ -0,0 +1,20 @@ +# ------------------------------------------------------------------------------------------------------ +# Provider configuration +# ------------------------------------------------------------------------------------------------------ +# Your global account subdomain +globalaccount = "yourglobalaccount" +region = "us10" +subaccount_name = "SAP Discovery Center Mission 4356" + +# ------------------------------------------------------------------------------------------------------ +# Project specific configuration (please adapt!) +# ------------------------------------------------------------------------------------------------------ + +subaccount_admins = ["another.user@test.com"] +subaccount_service_admins = ["another.user@test.com"] +cf_org_admins = ["another.user@test.com"] +cf_org_users = ["another.user@test.com"] +cf_space_managers = ["another.user@test.com", "you@test.com"] +cf_space_developers = ["another.user@test.com", "you@test.com"] + +custom_idp = "sap.ids" diff --git a/released/discovery_center/mission_4356/step1/variables.tf b/released/discovery_center/mission_4356/step1/variables.tf index 4cf8a08e..f5049343 100644 --- a/released/discovery_center/mission_4356/step1/variables.tf +++ b/released/discovery_center/mission_4356/step1/variables.tf @@ -21,13 +21,47 @@ variable "subaccount_name" { default = "UC - Deliver Connected Experiences with a single view of Material Availability" } -# cf org name -variable "cf_org_name" { +variable "custom_idp" { + type = string + description = "Defines the custom IdP" + default = "" +} + +variable "origin" { + type = string + description = "Defines the origin of the identity provider" + default = "sap.ids" + # The value for the origin can be defined + # but are normally set to "sap.ids", "sap.default" or "sap.custom" +} + +variable "cf_space_name" { + type = string + description = "Name of the Cloud Foundry space." + default = "dev" + + validation { + condition = can(regex("^.{1,255}$", var.cf_space_name)) + error_message = "The Cloud Foundry space name must not be emtpy and not exceed 255 characters." + } +} + +variable "cf_landscape_label" { type = string - description = "Cloud Foundry Org Name" - default = "cloud-foundry" + description = "In case there are multiple environments available for a subaccount, you can use this label to choose with which one you want to go. If nothing is given, we take by default the first available." + default = "" } +variable "cf_org_name" { + type = string + description = "Name of the Cloud Foundry org." + default = "mission-4356" + + 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." + } +} # Region variable "region" { type = string @@ -82,9 +116,9 @@ variable "service_plan__sap_business_app_studio" { } } -### +# ------------------------------------------------------------------------------------------------------ # Entitlements -### +# ------------------------------------------------------------------------------------------------------ variable "entitlements" { type = list(object({ service_name = string @@ -122,33 +156,54 @@ variable "appstudio_developers" { default = ["jane.doe@test.com", "john.doe@test.com"] } -variable "appstudio_admin" { +variable "appstudio_admins" { type = list(string) description = "Business Application Studio Administrator" default = ["jane.doe@test.com", "john.doe@test.com"] } -variable "cloudconnector_admin" { +variable "cloudconnector_admins" { type = list(string) description = "Cloud Connector Administrator" default = ["jane.doe@test.com", "john.doe@test.com"] } -variable "conn_dest_admin" { +variable "conn_dest_admins" { type = list(string) description = "Connectivity and Destination Administrator" default = ["jane.doe@test.com", "john.doe@test.com"] } -variable "int_provisioner" { +variable "int_provisioners" { type = list(string) description = "Integration Provisioner" default = ["jane.doe@test.com", "john.doe@test.com"] } -# Cloudfoundry environment label -variable "cf_environment_label" { - type = string - description = "The Cloudfoundry environment label" - default = "cf-us10" + +variable "cf_org_users" { + type = list(string) + description = "CF Org Users" + default = ["jane.doe@test.com", "john.doe@test.com"] } + +variable "cf_org_admins" { + type = list(string) + description = "List of users to set as Cloudfoundry org administrators." +} + +variable "cf_space_managers" { + type = list(string) + description = "Defines the colleagues who are added to a CF space as space manager." +} + +variable "cf_space_developers" { + type = list(string) + description = "Defines the colleagues who are added to a CF space as space developer." +} + +variable "create_tfvars_file_for_step2" { + type = bool + description = "Switch to enable the creation of the tfvars file for step 2." + default = false +} \ No newline at end of file diff --git a/released/discovery_center/mission_4356/step2/main.tf b/released/discovery_center/mission_4356/step2/main.tf index b4812ee4..77ee7c20 100644 --- a/released/discovery_center/mission_4356/step2/main.tf +++ b/released/discovery_center/mission_4356/step2/main.tf @@ -9,25 +9,31 @@ resource "cloudfoundry_space" "dev" { ###################################################################### # add org and space users and managers ###################################################################### +# Define Org User role resource "cloudfoundry_org_role" "organization_user" { for_each = toset(var.cf_org_users) username = each.value type = "organization_user" org = var.cf_org_id + origin = var.origin } - +# Define Org Manager role resource "cloudfoundry_org_role" "organization_manager" { - for_each = toset(var.cf_org_admins) - username = each.value - type = "organization_manager" - org = var.cf_org_id + for_each = toset(var.cf_org_admins) + username = each.value + type = "organization_manager" + org = var.cf_org_id + origin = var.origin + depends_on = [cloudfoundry_org_role.organization_user] } + resource "cloudfoundry_space_role" "space_developer" { for_each = toset(var.cf_space_developers) username = each.value type = "space_developer" space = cloudfoundry_space.dev.id + origin = var.origin depends_on = [cloudfoundry_org_role.organization_user, cloudfoundry_org_role.organization_manager] } @@ -36,5 +42,6 @@ resource "cloudfoundry_space_role" "space_manager" { username = each.value type = "space_manager" space = cloudfoundry_space.dev.id + origin = var.origin depends_on = [cloudfoundry_org_role.organization_user, cloudfoundry_org_role.organization_manager] } \ No newline at end of file diff --git a/released/discovery_center/mission_4356/step2/output.tf b/released/discovery_center/mission_4356/step2/output.tf index ad4178cd..742f4536 100644 --- a/released/discovery_center/mission_4356/step2/output.tf +++ b/released/discovery_center/mission_4356/step2/output.tf @@ -2,10 +2,6 @@ output "subaccount_id" { value = var.subaccount_id } -output "cf_landscape_label" { - value = var.cf_landscape_label -} - output "cf_org_id" { value = var.cf_org_id } diff --git a/released/discovery_center/mission_4356/step2/variables.tf b/released/discovery_center/mission_4356/step2/variables.tf index 438dc703..65b1f80d 100644 --- a/released/discovery_center/mission_4356/step2/variables.tf +++ b/released/discovery_center/mission_4356/step2/variables.tf @@ -1,14 +1,41 @@ -variable "cf_api_url" { - type = string +variable "globalaccount" { + type = string + description = "Defines the global account" + default = "yourglobalaccount" } -variable "cf_landscape_label" { - type = string +variable "cli_server_url" { + type = string + description = "Defines the CLI server URL" + default = "https://cli.btp.cloud.sap" +} + +variable "cf_api_url" { + type = string + description = "The Cloud Foundry API endpoint from the Cloud Foundry environment instance." } variable "cf_org_id" { type = string } +variable "cf_space_name" { + type = string + description = "Name of the Cloud Foundry space." + default = "dev" + + validation { + condition = can(regex("^.{1,255}$", var.cf_space_name)) + error_message = "The Cloud Foundry space name must not be emtpy and not exceed 255 characters." + } +} + +variable "origin" { + type = string + description = "Defines the origin of the identity provider" + default = "sap.ids" + # The value for the origin can be defined + # but are normally set to "sap.ids", "sap.default" or "sap.custom" +} variable "subaccount_id" { type = string