Skip to content

Add DC Mission 3808 #222

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jun 28, 2024
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
54 changes: 54 additions & 0 deletions released/discovery_center/mission_3808/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# SAP Discovery Center mission - Onboarding & First Steps to SAP Cloud ALM

## Overview

This terraform script shows how to set up the SAP Discovery Center Mission - [Onboarding & First Steps to SAP Cloud ALM](https://discovery-center.cloud.sap/protected/index.html#/missiondetail/3808/3857)

## Content of setup

The setup comprises the following resources:

- Creation of the SAP BTP subaccount
- Entitlements of services
- Subscriptions to applications
- Role collection assignments to users

## Deploying the resources

Make sure that you are familiar with SAP BTP and know both the [Get Started with btp-terraform-samples](https://github.com/SAP-samples/btp-terraform-samples/blob/main/GET_STARTED.md) and the [Get Started with the Terraform Provider for BTP](https://developers.sap.com/tutorials/btp-terraform-get-started.html)

To deploy the resources you must:

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 BTP_PASSWORD ='<Password of your BTP user>'
```

2. Change the variables in the `sample.tfvars` file 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: jane.doe@test.com`.


3. Initialize your workspace:

```bash
terraform init
```

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

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

5. Apply your configuration to provision the resources:

```bash
terraform apply -var-file="sample.tfvars"
```
154 changes: 154 additions & 0 deletions released/discovery_center/mission_3808/step1/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# ------------------------------------------------------------------------------------------------------
# Subaccount setup for DC mission 4104
# ------------------------------------------------------------------------------------------------------
# Setup subaccount domain (to ensure uniqueness in BTP global account)
resource "random_uuid" "subaccount_domain_suffix" {}

locals {
random_uuid = random_uuid.subaccount_domain_suffix.result
subaccount_domain = lower(replace("mission-3808-${local.random_uuid}", "_", "-"))
subaccount_cf_org = substr(replace("${local.subaccount_domain}", "-", ""), 0, 32)
}

# ------------------------------------------------------------------------------------------------------
# Creation of subaccount
# ------------------------------------------------------------------------------------------------------
resource "btp_subaccount" "dc_mission" {
name = var.subaccount_name
subdomain = local.subaccount_domain
region = lower(var.region)
}

# ------------------------------------------------------------------------------------------------------
# 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
}


# ------------------------------------------------------------------------------------------------------
# CLOUDFOUNDRY PREPARATION
# ------------------------------------------------------------------------------------------------------
#
# Fetch all available environments for the subaccount
data "btp_subaccount_environments" "all" {
subaccount_id = btp_subaccount.dc_mission.id
}
# ------------------------------------------------------------------------------------------------------
# Take the landscape label from the first CF environment if no environment label is provided
# (this replaces the previous null_resource)
# ------------------------------------------------------------------------------------------------------
resource "terraform_data" "replacement" {
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
}
# ------------------------------------------------------------------------------------------------------
# Create the Cloud Foundry environment instance
# ------------------------------------------------------------------------------------------------------
resource "btp_subaccount_environment_instance" "cloudfoundry" {
subaccount_id = btp_subaccount.dc_mission.id
name = local.subaccount_cf_org
environment_type = "cloudfoundry"
service_name = "cloudfoundry"
plan_name = "standard"
landscape_label = terraform_data.replacement.output

parameters = jsonencode({
instance_name = local.subaccount_cf_org
})
}

# ------------------------------------------------------------------------------------------------------
# SERVICES
# ------------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------------------------------
# Setup SAP Cloud Transport Management
# ------------------------------------------------------------------------------------------------------
# Entitle
resource "btp_subaccount_entitlement" "alm" {
subaccount_id = btp_subaccount.dc_mission.id
service_name = "alm-ts"
plan_name = "standard"
}
# Add subscription
resource "btp_subaccount_subscription" "alm" {
subaccount_id = btp_subaccount.dc_mission.id
app_name = "alm-ts"
plan_name = "standard"
depends_on = [btp_subaccount_entitlement.alm]
}

# ------------------------------------------------------------------------------------------------------
# Setup SAP Cloud Integration Automation
# ------------------------------------------------------------------------------------------------------
# Entitle
resource "btp_subaccount_entitlement" "cias" {
subaccount_id = btp_subaccount.dc_mission.id
service_name = "cias"
plan_name = "standard"
}
# Add subscription
resource "btp_subaccount_subscription" "cias" {
subaccount_id = btp_subaccount.dc_mission.id
app_name = "cias"
plan_name = "standard"
depends_on = [btp_subaccount_entitlement.cias]
}

# ------------------------------------------------------------------------------------------------------
# Setup SAP Cloud ALM API
# ------------------------------------------------------------------------------------------------------
# Entitle
resource "btp_subaccount_entitlement" "sapcloudalmapis" {
subaccount_id = btp_subaccount.dc_mission.id
service_name = "SAPCloudALMAPIs"
plan_name = "standard"
amount = 1
}

# ------------------------------------------------------------------------------------------------------
# USERS AND ROLES
# ------------------------------------------------------------------------------------------------------
#
# ------------------------------------------------------------------------------------------------------
# Assign role collection "Subaccount Administrator"
# ------------------------------------------------------------------------------------------------------
resource "btp_subaccount_role_collection_assignment" "subaccount_admin" {
for_each = toset("${var.subaccount_admins}")
subaccount_id = btp_subaccount.dc_mission.id
role_collection_name = "Subaccount Administrator"
user_name = each.value
depends_on = [btp_subaccount.dc_mission]
}


# ------------------------------------------------------------------------------------------------------
# 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 = "${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"]}"
cf_org_name = "${jsondecode(btp_subaccount_environment_instance.cloudfoundry.labels)["Org Name"]}"

origin_key = "${var.origin_key}"

cf_space_name = "${var.cf_space_name}"

cf_org_admins = ${jsonencode(var.cf_org_admins)}
cf_space_developers = ${jsonencode(var.cf_space_developers)}
cf_space_managers = ${jsonencode(var.cf_space_managers)}

EOT
filename = "../step2/terraform.tfvars"
}
13 changes: 13 additions & 0 deletions released/discovery_center/mission_3808/step1/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
terraform {
required_providers {
btp = {
source = "SAP/btp"
version = "~> 1.4.0"
}
}
}

provider "btp" {
globalaccount = var.globalaccount
cli_server_url = var.cli_server_url
}
28 changes: 28 additions & 0 deletions released/discovery_center/mission_3808/step1/sample.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# ------------------------------------------------------------------------------------------------------
# Provider configuration
# ------------------------------------------------------------------------------------------------------
# Your global account subdomain
globalaccount = "xxxxxxxx-xxxxxxx-xxxxxxx-xxxxxxxx-xxxxxx"

# The CLI server URL (needs to be set to null if you are using the default CLI server)
cli_server_url = null

# Region for your subaccount
region = "us20"

# Name of your sub account
subaccount_name = "SAP Discovery Center Mission 3808"

# custom_idp = "sap.custom"

# ------------------------------------------------------------------------------------------------------
# USER ROLES
# ------------------------------------------------------------------------------------------------------
subaccount_admins = ["another.user@test.com"]
subaccount_service_admins = ["another.user@test.com"]

cf_org_admins = ["another.user@test.com"]
cf_space_managers = ["another.user@test.com", "you@test.com"]
cf_space_developers = ["another.user@test.com", "you@test.com"]

launchpad_admins = ["another.user@test.com", "you@test.com"]
116 changes: 116 additions & 0 deletions released/discovery_center/mission_3808/step1/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
variable "globalaccount" {
type = string
description = "The globalaccount subdomain where the sub account shall be created."
}

variable "subaccount_name" {
type = string
description = "The subaccount name."
default = "My SAP DC mission subaccount."
}

variable "cli_server_url" {
type = string
description = "The BTP CLI server URL."
default = "https://cli.btp.cloud.sap"
}

variable "region" {
type = string
description = "The region where the subaccount shall be created in."
default = "us20"
}

variable "subaccount_admins" {
type = list(string)
description = "Defines the colleagues who are added to each subaccount as emergency administrators."

# 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 subaccount admins."
}
}


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

variable "origin_key" {
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_landscape_label" {
type = string
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-3808"

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."
}
}

variable "cf_org_admins" {
type = list(string)
description = "List of users to set as Cloudfoundry org administrators."

# add validation to check if 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_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_space_managers" {
type = list(string)
description = "Defines the colleagues who are added to a CF space as space manager."

# add validation to check if admins 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 CF space managers."
}
}

variable "cf_space_developers" {
type = list(string)
description = "Defines the colleagues who are added to a CF space as space developer."

# add validation to check if admins 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 "create_tfvars_file_for_step2" {
type = bool
description = "Switch to enable the creation of the tfvars file for step 2."
default = false
}
Loading