From c9762be8484bea3a4d171233ef037327bd957e9c Mon Sep 17 00:00:00 2001 From: "Kwiatosz, Krzysztof" Date: Thu, 5 Sep 2024 11:52:58 +0200 Subject: [PATCH] First commit --- .reuse/dep5 | 6 +- README.md | 59 ++--------- docs/README.md | 39 -------- docs/contributor/README.md | 1 - docs/user/README.md | 14 --- docs/user/_sidebar.md | 1 - main.tf | 199 +++++++++++++++++++++++++++++++++++++ output.tf | 9 ++ provider.tf | 15 +++ variables.tf | 56 +++++++++++ 10 files changed, 291 insertions(+), 108 deletions(-) delete mode 100644 docs/README.md delete mode 100644 docs/contributor/README.md delete mode 100644 docs/user/README.md delete mode 100644 docs/user/_sidebar.md create mode 100644 main.tf create mode 100644 output.tf create mode 100644 provider.tf create mode 100644 variables.tf diff --git a/.reuse/dep5 b/.reuse/dep5 index 96d499f..c40825f 100755 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -1,7 +1,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: -Upstream-Contact: -Source: +Upstream-Name: terraform-module +Upstream-Contact: krzysztof.kwiatosz@sap.com +Source: https://github.com/kyma-project/terraform-module Disclaimer: The code in this project may include calls to APIs ("API Calls") of SAP or third-party products or services developed outside of this project ("External Products"). diff --git a/README.md b/README.md index 5714e17..874bda4 100644 --- a/README.md +++ b/README.md @@ -1,55 +1,14 @@ -> **NOTE:** This is a general template that you can use for a project README.md. Except for the mandatory sections, use only those sections that suit your use case but keep the proposed section order. -> -> Mandatory sections: -> - `Overview` -> - `Prerequisites`, if there are any requirements regarding hard- or software -> - `Installation` -> - `Contributing` - do not change this! -> - `Code of Conduct` - do not change this! -> - `Licensing` - do not change this! +> **TIP:** Apart from the {Module Name} heading, you can use your own titles for the remaining sections. You can also add more module-specific sections. -# {Project Title} - -> Modify the title and insert the name of your project. Use Heading 1 (H1). +# {Module Name} +> Modify the title and insert the name of your module. Use Heading 1 (H1). ## Overview - +> Provide a description of your module and its components. Describe its features and functionalities. +> You can divide this section to the relevant subsections. -> Provide a description of the project's functionality. -> -> If it is an example README.md, describe what the example illustrates. +## Useful Links (Optional) +> Provide links to the most relevant module documentation (tutorials, technical references, resources, etc.). -## Prerequisites - -> List the requirements to run the project or example. - -## Installation - -> Explain the steps to install your project. If there are multiple installation options, mention the recommended one and include others in a separate document. Create an ordered list for each installation task. -> -> If it is an example README.md, describe how to build, run locally, and deploy the example. Format the example as code blocks and specify the language, highlighting where possible. Explain how you can validate that the example ran successfully. For example, define the expected output or commands to run which check a successful deployment. -> -> Add subsections (H3) for better readability. - -## Usage - -> Explain how to use the project. You can create multiple subsections (H3). Include the instructions or provide links to the related documentation. - -## Development - -> Add instructions on how to develop the project or example. It must be clear what to do and, for example, how to trigger the tests so that other contributors know how to make their pull requests acceptable. Include the instructions or provide links to related documentation. - -## Contributing - - -See the [Contributing Rules](CONTRIBUTING.md). - -## Code of Conduct - - -See the [Code of Conduct](CODE_OF_CONDUCT.md) document. - -## Licensing - - -See the [license](./LICENSE) file. +## Feedback (Optional) +> Describe how users can provide feedback. \ No newline at end of file diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 84aca7b..0000000 --- a/docs/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Docs - -## Overview - -The `docs` folder contains two subfolders - `user` and `contributor`. - -The `user` subfolder contains the end-user documentation, which is displayed on the [Kyma website](https://kyma-project.io/#/). Depending on your module needs, the subfolder must include overview, usage, or technical reference documents. To display the content on the website properly, create a `_sidebar.md` file in the `user` subfolder and list the documents it contains there. For more information on how to publish user documentation, follow [this guide](https://github.com/kyma-project/community/blob/main/docs/guidelines/content-guidelines/01-user-docs.md). - -The `contributor` subfolder includes any developer-related documentation to help them manually install, develop, and operate a module. - -To have a common structure across all modules, all documents must be properly numbered according to the following structure: - -> **NOTE:** It is suggested to use the following titles if you have the content that matches them; otherwise use your own, more suitable titles, or simply skip the ones you find irrelevant. - - - 00-xx-overview - - 01-xx-tutorial/configuration - - 02-xx-usage - - 03-xx-troubleshooting - -where `xx` is the number of the given document. For example: - - ```bash - 00-00-overview-telemetry-manager - 00-10-overview-logs - 00-20-overview-traces - 00-30-overview-metrics - 01-10-configure-logs - 01-20-configure-traces - 01-30-configure-metrics - 02-10-use-logs - 02-20-use-traces - 02-30-use-metrics - (...) - ``` -> **NOTE:** Before introducing [docsify](https://docsify.js.org/#/?id=docsify), we agreed to use the `10`, `20`, `30` numbering. It was to help maintain the proper order of docs if they were rendered automatically on the website. With docsify, you manually add the content to the `_sidebar.md` file, and docs are displayed in the order you add them. However, this numbering is still recommended to have the unified structure of the docs in the module repositories. - -If you have other content that does not fit into the above topics, create your own 04-10-module-specific document(s). - -You can divide your documentation into subfolders to avoid having too many documents in one `docs/user` or `docs/contributor` folder. For example, if you have many technical reference documents, you can create a `technical reference` subfolder in `docs/user` and keep relevant documentation there. Each subfolder in the `user` folder must have its own `_sidebar.md` file with the links to the main module page and the list of docs it contains. \ No newline at end of file diff --git a/docs/contributor/README.md b/docs/contributor/README.md deleted file mode 100644 index 9a22d6f..0000000 --- a/docs/contributor/README.md +++ /dev/null @@ -1 +0,0 @@ -In this folder, you can add any developer-related documentation, for example, advanced installation options, testing strategy, governance, etc. \ No newline at end of file diff --git a/docs/user/README.md b/docs/user/README.md deleted file mode 100644 index 1c6854d..0000000 --- a/docs/user/README.md +++ /dev/null @@ -1,14 +0,0 @@ -> **TIP:** Apart from the {Module Name} heading, you can use your own titles for the remaining sections. You can also add more module-specific sections. - -# {Module Name} -> Modify the title and insert the name of your module. Use Heading 1 (H1). - -## Overview -> Provide a description of your module and its components. Describe its features and functionalities. Mention the scope and add information on the CustomResourceDefinitions (CRDs). -> You can divide this section to the relevant subsections. - -## Useful Links (Optional) -> Provide links to the most relevant module documentation (tutorials, technical references, resources, etc.). - -## Feedback (Optional) -> Describe how users can provide feedback. \ No newline at end of file diff --git a/docs/user/_sidebar.md b/docs/user/_sidebar.md deleted file mode 100644 index 467416e..0000000 --- a/docs/user/_sidebar.md +++ /dev/null @@ -1 +0,0 @@ -Use this file to create an unordered list of documents you want to display on the [Kyma website](https://kyma-project.io). The list serves to navigate through the user documentation. For more information, visit the [User documentation](https://github.com/kyma-project/community/blob/main/docs/guidelines/content-guidelines/01-user-docs.md) guide. \ No newline at end of file diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..8ea6e9f --- /dev/null +++ b/main.tf @@ -0,0 +1,199 @@ +# "kyma.tf" + +resource "btp_subaccount_entitlement" "kyma" { + subaccount_id = btp_subaccount.subaccount.id + service_name = "kymaruntime" + plan_name = var.BTP_KYMA_PLAN + amount = 1 +} + +resource "btp_subaccount_environment_instance" "kyma" { + subaccount_id = btp_subaccount.subaccount.id + name = "${var.BTP_SUBACCOUNT}-kyma" + environment_type = "kyma" + service_name = btp_subaccount_entitlement.kyma.service_name + plan_name = btp_subaccount_entitlement.kyma.plan_name + parameters = jsonencode({ + modules = { + list = [ + { + name = "api-gateway" + channel = "fast" + }, + { + name = "istio" + channel = "fast" + }, + { + name = "btp-operator" + channel = "fast" + } + ] + } + oidc = { + groupsClaim = "groups" + signingAlgs = ["RS256"] + usernameClaim = "sub" + usernamePrefix = "-" + clientID = jsondecode(btp_subaccount_service_binding.identity_application_binding.credentials).clientid + issuerURL = "https://${var.BTP_CUSTOM_IAS_TENANT}.${var.BTP_CUSTOM_IAS_DOMAIN}" + } + name = "${var.BTP_SUBACCOUNT}-kyma" + region = var.BTP_KYMA_REGION + administrators = [ + var.BTP_BOT_USER + ] + }) + timeouts = { + create = "60m" + update = "30m" + delete = "60m" + } +} + +data "http" "kubeconfig" { + url = jsondecode(btp_subaccount_environment_instance.kyma.labels).KubeconfigURL + retry { + attempts = 2 + max_delay_ms = 2000 + min_delay_ms = 1000 + } + lifecycle { + postcondition { + condition = can(regex("kind: Config",self.response_body)) + error_message = "Invalid content of downloaded kubeconfig" + } + } +} + +locals { + id_token = jsondecode(data.http.token.response_body).id_token + kubeconfig_oidc = yamldecode(data.http.kubeconfig.response_body) +} + +data "jq_query" "kubeconfig" { + data = jsonencode(yamldecode(data.http.kubeconfig.response_body)) + query = "del(.users[] | .user | .exec) | .users[] |= . + { user: { token: ${jsonencode(local.id_token)} } }" +} + +resource "local_sensitive_file" "kubeconfig-yaml" { + filename = "kubeconfig.yaml" + content = yamlencode(jsondecode(data.jq_query.kubeconfig.result) ) +} + +#"oidc.tf" + +resource "btp_subaccount_entitlement" "identity" { + subaccount_id = btp_subaccount.subaccount.id + service_name = "identity" + plan_name = "application" +} + +# custom idp +resource "btp_subaccount_trust_configuration" "custom_idp" { + subaccount_id = btp_subaccount.subaccount.id + identity_provider = "${var.BTP_CUSTOM_IAS_TENANT}.${var.BTP_CUSTOM_IAS_DOMAIN}" + name = "${var.BTP_SUBACCOUNT}-${var.BTP_CUSTOM_IAS_TENANT}" + depends_on = [btp_subaccount_entitlement.identity] +} + +data "btp_subaccount_service_plan" "identity_application" { + depends_on = [btp_subaccount_entitlement.identity] + subaccount_id = btp_subaccount.subaccount.id + offering_name = "identity" + name = "application" +} + +resource "btp_subaccount_service_instance" "identity_application" { + depends_on = [btp_subaccount_trust_configuration.custom_idp] + subaccount_id = btp_subaccount.subaccount.id + name = "${var.BTP_SUBACCOUNT}-${var.BTP_CUSTOM_IAS_TENANT}-oidc-app" + serviceplan_id = data.btp_subaccount_service_plan.identity_application.id + parameters = jsonencode({ + user-access = "public" + oauth2-configuration = { + grant-types = [ + "authorization_code", + "authorization_code_pkce_s256", + "password", + "refresh_token" + ], + token-policy = { + token-validity = 3600, + refresh-validity = 15552000, + refresh-usage-after-renewal = "off", + refresh-parallel = 3, + access-token-format = "default" + }, + public-client = true, + redirect-uris = [ + "https://dashboard.kyma.cloud.sap", + "https://dashboard.dev.kyma.cloud.sap", + "https://dashboard.stage.kyma.cloud.sap", + "http://localhost:8000" + ] + }, + subject-name-identifier = { + attribute = "mail", + fallback-attribute = "none" + }, + default-attributes = null, + assertion-attributes = { + email = "mail", + groups = "companyGroups", + first_name = "firstName", + last_name = "lastName", + login_name = "loginName", + mail = "mail", + scope = "companyGroups", + user_uuid = "userUuid", + locale = "language" + }, + name = "${var.BTP_SUBACCOUNT}-${var.BTP_CUSTOM_IAS_TENANT}-oidc-app", + display-name = "${var.BTP_SUBACCOUNT}-${var.BTP_CUSTOM_IAS_TENANT}-oidc-app" + }) +} + +resource "btp_subaccount_service_binding" "identity_application_binding" { + subaccount_id = btp_subaccount.subaccount.id + name = "${var.BTP_SUBACCOUNT}-${var.BTP_CUSTOM_IAS_TENANT}-oidc-app-binding" + service_instance_id = btp_subaccount_service_instance.identity_application.id + parameters = jsonencode({ + credential-type = "X509_GENERATED" + key-length = 4096 + validity = 1 + validity-type = "DAYS" + app-identifier = "kymaruntime" + }) +} + +locals { + idp = jsondecode(btp_subaccount_service_binding.identity_application_binding.credentials) +} + +data "http" "token" { + url = "${local.idp.url}/oauth2/token" + method = "POST" + request_headers = { + Content-Type = "application/x-www-form-urlencoded" + } + request_body = "grant_type=password&username=${var.BTP_BOT_USER}&password=${var.BTP_BOT_PASSWORD}&client_id=${local.idp.clientid}&scope=groups,email" +} + +#"provider-sm.tf" + +data "btp_subaccount_service_binding" "provider_sm" { + count = var.BTP_PROVIDER_SUBACCOUNT_ID == null ? 0 : 1 + # count = try(var.BTP_PROVIDER_SUBACCOUNT_ID, false) ? 1 : 0 + subaccount_id = var.BTP_PROVIDER_SUBACCOUNT_ID + name = "provider-sm-binding" +} + +#"subaccount.tf" + +resource "btp_subaccount" "subaccount" { + name = var.BTP_SUBACCOUNT + region = var.BTP_SA_REGION + subdomain = var.BTP_SUBACCOUNT +} + diff --git a/output.tf b/output.tf new file mode 100644 index 0000000..edaf467 --- /dev/null +++ b/output.tf @@ -0,0 +1,9 @@ +output "custom_service_manager_credentials" { + value = var.BTP_PROVIDER_SUBACCOUNT_ID == null ? null : jsondecode(one(data.btp_subaccount_service_binding.provider_sm).credentials) +} + +output "kubeconfig" { + value = yamlencode(jsondecode(data.jq_query.kubeconfig.result) ) +} + + diff --git a/provider.tf b/provider.tf new file mode 100644 index 0000000..df74659 --- /dev/null +++ b/provider.tf @@ -0,0 +1,15 @@ +terraform { + required_providers { + btp = { + source = "SAP/btp" + version = "1.5.0" + } + jq = { + source = "massdriver-cloud/jq" + } + http = { + source = "hashicorp/http" + version = "3.4.4" + } + } +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..a6e55a1 --- /dev/null +++ b/variables.tf @@ -0,0 +1,56 @@ +# we're using uppercase variable names, since in some cases (e.g Azure DevOps) the system variables are forced to be uppercase +# TF allows providing variable values as env variables of name name, case sensitive + +variable "BTP_KYMA_PLAN" { + type = string + description = "Plan name" + default = "gcp" +} + +variable "BTP_SUBACCOUNT" { + type = string + description = "Subaccount name" + default = "subaccount-name" +} + +variable "BTP_CUSTOM_IAS_TENANT" { + type = string + description = "Custom IAS tenant" + default = "custon-tenant" +} + +variable "BTP_CUSTOM_IAS_DOMAIN" { + type = string + description = "Custom IAS domain" + default = "accounts400.ondemand.com" +} + +variable "BTP_KYMA_REGION" { + type = string + description = "Kyma region" + default = "us-central1" +} + +variable "BTP_BOT_USER" { + type = string + description = "Bot account name" + default = "email@domain.com" +} + +variable "BTP_BOT_PASSWORD" { + type = string + description = "Bot account password" + default = "password" +} + +variable "BTP_PROVIDER_SUBACCOUNT_ID" { + type = string + description = "Subaccount ID" + default = null +} + +variable "BTP_SA_REGION" { + type = string + description = "Region name" + default = "us31" +}