|
| 1 | +# Setup of a Subaccount using BTP Terraform Provider |
| 2 | + |
| 3 | +In this exercise you will learn how to use the [Terraform Provider for SAP BTP](https://registry.terraform.io/providers/SAP/btp/latest/docs) to provision and manage resources in SAP BTP as well as [Cloudfoundry Terraform Provider](https://registry.terraform.io/providers/cloudfoundry/cloudfoundry/latest) to manage Cloudfoundry resources. |
| 4 | + |
| 5 | +## Step 1: Create a new directory |
| 6 | + |
| 7 | +To make use of Terraform you must create several configuration files using the [Terraform configuration language](https://developer.hashicorp.com/terraform/language). Create a new directory named `my-tf-handson`. |
| 8 | + |
| 9 | +Terraform expects a specific file layout for its configurations. Create the following empty files in the directory `my-tf-handson`: |
| 10 | + |
| 11 | +- `main.tf` - this file will contain the main configuration of the Terraform setup |
| 12 | +- `provider.tf` - this file will contain the provider configuration |
| 13 | +- `variables.tf` - this file will contain the variables to be used in the Terraform configuration |
| 14 | +- `terraform.tfvars` - this file will contain your specific variable values |
| 15 | + |
| 16 | +## Step 2: Setup Subaccount using Terraform |
| 17 | + |
| 18 | +- Open the file `provider.tf` and add the following content: |
| 19 | + |
| 20 | +```terraform |
| 21 | +terraform { |
| 22 | + required_providers { |
| 23 | + btp = { |
| 24 | + source = "sap/btp" |
| 25 | + version = "~> 1.12.0" |
| 26 | + } |
| 27 | + cloudfoundry = { |
| 28 | + source = "cloudfoundry/cloudfoundry" |
| 29 | + version = "~> 1.6.0" |
| 30 | + } |
| 31 | + } |
| 32 | +} |
| 33 | +
|
| 34 | +provider "btp" { |
| 35 | + globalaccount = var.globalaccount |
| 36 | + idp = var.idp |
| 37 | +} |
| 38 | +provider "cloudfoundry" { |
| 39 | + api_url = "https://api.cf.${var.region}.hana.ondemand.com" |
| 40 | + origin = var.idp |
| 41 | +} |
| 42 | +``` |
| 43 | + |
| 44 | +What have we done? First we defined which provider we want to use and which version of the provider we want to use. In this case we want to use the provider `sap/btp` in version `1.10.0` and cloudfoundry provider `cloudfoundry/cloudfoundry` in version `1.3.0`. Then we defined the provider configuration. In this case we need to provide the `globalaccount` and `idp` parameters where we reference a variable. We will define this variable in the next steps. |
| 45 | + |
| 46 | + > [!NOTE] |
| 47 | + > We do not need any authentication information in this file. We provided the authentication information via environment variables. |
| 48 | +
|
| 49 | +Next we must add the required variables to the `variables.tf` file. Open the file `variables.tf` and add the following content: |
| 50 | + |
| 51 | +```terraform |
| 52 | +variable "globalaccount" { |
| 53 | + type = string |
| 54 | + description = "The subdomain of the SAP BTP global account." |
| 55 | +} |
| 56 | +
|
| 57 | +variable "idp" { |
| 58 | + type = string |
| 59 | + description = "Orgin key of Identity Provider" |
| 60 | + default = null |
| 61 | +} |
| 62 | +variable "region" { |
| 63 | + type = string |
| 64 | + description = "The region where the project account shall be created in." |
| 65 | + default = "ap10" |
| 66 | +} |
| 67 | +variable "project_name" { |
| 68 | + type = string |
| 69 | + description = "The subaccount name." |
| 70 | + default = "proj-1234" |
| 71 | +
|
| 72 | + validation { |
| 73 | + condition = can(regex("^[a-zA-Z0-9_\\-]{1,200}", var.project_name)) |
| 74 | + error_message = "Provide a valid project name." |
| 75 | + } |
| 76 | +} |
| 77 | +variable "stage" { |
| 78 | + type = string |
| 79 | + description = "The stage/tier the account will be used for." |
| 80 | + default = "DEV" |
| 81 | +
|
| 82 | + validation { |
| 83 | + condition = contains(["DEV", "TST", "PRD"], var.stage) |
| 84 | + error_message = "Select a valid stage for the project account." |
| 85 | + } |
| 86 | +} |
| 87 | +variable "costcenter" { |
| 88 | + type = string |
| 89 | + description = "The cost center the account will be billed to." |
| 90 | + default = "1234567890" |
| 91 | +
|
| 92 | + validation { |
| 93 | + condition = can(regex("^[0-9]{10}", var.costcenter)) |
| 94 | + error_message = "Provide a valid cost center." |
| 95 | + } |
| 96 | +} |
| 97 | +variable "org_name" { |
| 98 | + type = string |
| 99 | + description = "Defines to which organization the project account shall belong to." |
| 100 | + default = "Exporter" |
| 101 | +} |
| 102 | +variable "bas_admins" { |
| 103 | + type = list(string) |
| 104 | + description = "List of users to assign the Administrator role." |
| 105 | +
|
| 106 | +} |
| 107 | +variable "bas_developers" { |
| 108 | + type = list(string) |
| 109 | + description = "List of users to assign the Developer role." |
| 110 | +} |
| 111 | +variable "bas_service_name" { |
| 112 | + type = string |
| 113 | + description = "Service name for Business Application Studio." |
| 114 | + default = "sapappstudio" |
| 115 | +
|
| 116 | +} |
| 117 | +variable "bas_plan" { |
| 118 | + type = string |
| 119 | + description = "Plan name for Business Application Studio." |
| 120 | + default = "standard-edition" |
| 121 | +} |
| 122 | +
|
| 123 | +variable "cf_landscape_label" { |
| 124 | + type = string |
| 125 | + description = "The region where the project account shall be created in." |
| 126 | + default = "cf-ap10" |
| 127 | +} |
| 128 | +variable "cf_plan" { |
| 129 | + type = string |
| 130 | + description = "Plan name for Cloud Foundry Runtime." |
| 131 | + default = "standard" |
| 132 | +} |
| 133 | +variable "cf_space_name" { |
| 134 | + type = string |
| 135 | + description = "The name of the Cloud Foundry space." |
| 136 | + default = "dev" |
| 137 | +} |
| 138 | +
|
| 139 | +``` |
| 140 | +We have now defined the variables which will be required for the provider configuration. We will provide the value for this variable via the `terraform.tfvars` file. |
| 141 | + |
| 142 | + - Open the file `terraform.tfvars` and add the following content: |
| 143 | + |
| 144 | +```terraform |
| 145 | +globalaccount = "inside-track-2023" |
| 146 | +idp = "aviss4yru-platform" |
| 147 | +project_name = "<YOUR LAST NAME>" |
| 148 | +
|
| 149 | +bas_service_name = "sapappstudio" |
| 150 | +bas_plan = "standard-edition" |
| 151 | + |
| 152 | + |
| 153 | +
|
| 154 | +cf_plan = "standard" |
| 155 | +``` |
| 156 | +- Update fields with your user details. |
| 157 | + |
| 158 | +The SAP BTP Global Account Subdomain can be found in the [SAP BTP Cockpit](https://apac.cockpit.btp.cloud.sap/cockpit/?idp=aviss4yru.accounts.ondemand.com#/globalaccount/6378f0c6-1b1e-4b10-8517-171cbec05c3e). |
| 159 | + |
| 160 | +- Open `main.tf` file and add the following content |
| 161 | + |
| 162 | +```terraform |
| 163 | +locals { |
| 164 | + project_subaccount_name = "${var.org_name} | ${var.project_name}: CF - ${var.stage}" |
| 165 | + project_subaccount_domain = lower(replace("${var.org_name}-${var.project_name}-${var.stage}", " ", "")) |
| 166 | + project_subaccount_cf_org = replace("${var.org_name}_${lower(var.project_name)}-${lower(var.stage)}", " ", "_") |
| 167 | +} |
| 168 | +resource "btp_subaccount" "project" { |
| 169 | + name = local.project_subaccount_name |
| 170 | + subdomain = local.project_subaccount_domain |
| 171 | + region = lower(var.region) |
| 172 | + labels = { |
| 173 | + "stage" = ["${var.stage}"], |
| 174 | + "costcenter" = ["${var.costcenter}"] |
| 175 | + } |
| 176 | +} |
| 177 | +resource "btp_subaccount_entitlement" "bas" { |
| 178 | + subaccount_id = btp_subaccount.project.id |
| 179 | + service_name = var.bas_service_name |
| 180 | + plan_name = var.bas_plan |
| 181 | +} |
| 182 | +
|
| 183 | +resource "btp_subaccount_subscription" "bas" { |
| 184 | + subaccount_id = btp_subaccount.project.id |
| 185 | + app_name = var.bas_service_name |
| 186 | + plan_name = var.bas_plan |
| 187 | + depends_on = [btp_subaccount_entitlement.bas] |
| 188 | +} |
| 189 | +
|
| 190 | +resource "btp_subaccount_role_collection_assignment" "bas_admin" { |
| 191 | + for_each = toset(var.bas_admins) |
| 192 | + subaccount_id = btp_subaccount.project.id |
| 193 | + role_collection_name = "Business_Application_Studio_Administrator" |
| 194 | + user_name = each.value |
| 195 | + depends_on = [btp_subaccount_subscription.bas] |
| 196 | +} |
| 197 | +
|
| 198 | +resource "btp_subaccount_role_collection_assignment" "bas_developer" { |
| 199 | + for_each = toset(var.bas_developers) |
| 200 | + subaccount_id = btp_subaccount.project.id |
| 201 | + role_collection_name = "Business_Application_Studio_Developer" |
| 202 | + user_name = each.value |
| 203 | + depends_on = [btp_subaccount_subscription.bas] |
| 204 | +} |
| 205 | +resource "btp_subaccount_environment_instance" "cloudfoundry" { |
| 206 | + subaccount_id = btp_subaccount.project.id |
| 207 | + name = local.project_subaccount_cf_org |
| 208 | + landscape_label = var.cf_landscape_label |
| 209 | + environment_type = "cloudfoundry" |
| 210 | + service_name = "cloudfoundry" |
| 211 | + plan_name = var.cf_plan |
| 212 | + parameters = jsonencode({ |
| 213 | + instance_name = local.project_subaccount_cf_org |
| 214 | + }) |
| 215 | + timeouts = { |
| 216 | + create = "1h" |
| 217 | + update = "35m" |
| 218 | + delete = "30m" |
| 219 | + } |
| 220 | +} |
| 221 | +
|
| 222 | +resource "cloudfoundry_space" "space" { |
| 223 | + name = var.cf_space_name |
| 224 | + org = btp_subaccount_environment_instance.cloudfoundry.platform_id |
| 225 | +} |
| 226 | +
|
| 227 | +``` |
| 228 | +### Apply the Terraform configuration |
| 229 | + |
| 230 | +Now the moment has come to apply the Terraform configuration for the first time. Open a terminal window and execute the following commands: |
| 231 | + |
| 232 | +1. Initialize the Terraform configuration to download the required provider: |
| 233 | + |
| 234 | +```bash |
| 235 | +terraform init |
| 236 | +``` |
| 237 | + |
| 238 | +> [!NOTE] |
| 239 | +> Check your files. You should have a new folder called `.terraform` as well as new file called `.terraform.lock.hcl` in your directory. This means that the Terraform provider has been successfully downloaded and the version constraints are stored for your setup. |
| 240 | +
|
| 241 | +2. Plan the Terraform configuration to see what will be created: |
| 242 | + |
| 243 | +```bash |
| 244 | +terraform plan |
| 245 | +``` |
| 246 | +3. Apply the Terraform configuration to create the subaccount: |
| 247 | + |
| 248 | +```bash |
| 249 | +terraform apply |
| 250 | + |
| 251 | +``` |
| 252 | + You will be prompted to confirm the creation of the subaccount. Type `yes` and press `Enter` to continue. |
| 253 | + |
| 254 | + Go to the BTP cockpit and check the resources you have created. Follow the URL to access [BTP Accounts Cockpit](https://apac.cockpit.btp.cloud.sap/cockpit/?idp=aviss4yru.accounts.ondemand.com#/globalaccount/6378f0c6-1b1e-4b10-8517-171cbec05c3e). |
| 255 | + |
| 256 | + |
| 257 | +## Summary |
| 258 | + |
| 259 | +You have successfully created an SAP BTP Subaccount with active resources using Terraform. Now, imagine you already have an existing subaccount and want to bring it under Terraform's management. This exercise will guide you through that process. |
| 260 | + |
| 261 | +Continue to - [Exercise 2 - Export BTP Subaccount Using BTP Terraform Exporter](../EXERCISE2/README.md). |
0 commit comments