From 7845ad97b584ce52ed1f442f101b00a9a202670a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20W=C3=BCrbach?= Date: Wed, 12 Jun 2024 13:13:52 +0200 Subject: [PATCH 1/2] feat: toggleable backstage --- .github/workflows/ci.yaml | 12 +- .tflint.hcl | 10 ++ Makefile | 29 +++- README.md | 160 +++++++++++++----- examples/with-backstage/README.md | 142 ---------------- .../with-backstage/backstage-humanitec.tf | 128 -------------- .../with-backstage/create-gh-app/index.js | 153 ----------------- examples/with-backstage/main.tf | 20 --- .../with-backstage/terraform.tfvars.example | 27 --- examples/with-backstage/variables.tf | 57 ------- main.tf | 96 ++++++++--- modules/base/README.md | 55 ++++++ modules/base/outputs.tf | 10 ++ modules/base/providers.tf | 9 +- modules/base/terraform.tfvars.example | 45 +++++ modules/base/variables.tf | 6 - modules/github/README.md | 50 ++++++ .../gcp-github.tf => modules/github/gcp.tf | 4 +- .../github/main.tf | 41 +---- .../github/providers.tf | 24 +-- modules/github/terraform.tfvars.example | 18 ++ modules/github/variables.tf | 45 +++++ modules/gke/outputs.tf | 9 + modules/gke/providers.tf | 27 +-- modules/htc_res_defs/README.md | 46 +++++ modules/htc_res_defs/main.tf | 25 +++ modules/htc_res_defs/providers.tf | 4 +- modules/htc_res_defs/terraform.tfvars.example | 24 +++ modules/network/README.md | 43 +++++ modules/network/main.tf | 6 +- modules/network/terraform.tfvars.example | 15 ++ modules/network/variables.tf | 33 ---- modules/portal-backstage/README.md | 42 +++++ modules/portal-backstage/main.tf | 58 +++++++ modules/portal-backstage/providers.tf | 13 ++ .../portal-backstage/terraform.tfvars.example | 24 +++ modules/portal-backstage/variables.tf | 40 +++++ providers.tf | 63 +++++++ terraform.tfvars.example | 16 +- variables.tf | 29 +++- 40 files changed, 922 insertions(+), 736 deletions(-) create mode 100644 .tflint.hcl delete mode 100644 examples/with-backstage/README.md delete mode 100644 examples/with-backstage/backstage-humanitec.tf delete mode 100644 examples/with-backstage/create-gh-app/index.js delete mode 100644 examples/with-backstage/main.tf delete mode 100644 examples/with-backstage/terraform.tfvars.example delete mode 100644 examples/with-backstage/variables.tf create mode 100644 modules/base/README.md create mode 100644 modules/base/terraform.tfvars.example create mode 100644 modules/github/README.md rename examples/with-backstage/gcp-github.tf => modules/github/gcp.tf (94%) rename examples/with-backstage/backstage-github.tf => modules/github/main.tf (52%) rename examples/with-backstage/provider.tf => modules/github/providers.tf (56%) create mode 100644 modules/github/terraform.tfvars.example create mode 100644 modules/github/variables.tf create mode 100644 modules/htc_res_defs/README.md create mode 100644 modules/htc_res_defs/terraform.tfvars.example create mode 100644 modules/network/README.md create mode 100644 modules/network/terraform.tfvars.example create mode 100644 modules/portal-backstage/README.md create mode 100644 modules/portal-backstage/main.tf create mode 100644 modules/portal-backstage/providers.tf create mode 100644 modules/portal-backstage/terraform.tfvars.example create mode 100644 modules/portal-backstage/variables.tf create mode 100644 providers.tf diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e9471779..a583c9f2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,7 +20,7 @@ jobs: - name: Install terraform-docs run: | WORK_DIR=$(mktemp -d) - curl -Lo ${WORK_DIR}/terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.16.0/terraform-docs-v0.16.0-$(uname)-amd64.tar.gz + curl -Lo ${WORK_DIR}/terraform-docs.tar.gz https://github.com/terraform-docs/terraform-docs/releases/download/v0.18.0/terraform-docs-v0.18.0-$(uname)-amd64.tar.gz cd ${WORK_DIR} tar -xzf terraform-docs.tar.gz chmod +x terraform-docs @@ -31,11 +31,11 @@ jobs: - name: Check git diff is clean (all files generated should be committed) run: git diff --exit-code - - name: Terraform Format Check - run: make fmt-check - - - name: Stub Github App credentials (required for validation) - run: cd ./examples/with-backstage && STUB_FILE=1 node create-gh-app/index.js + - uses: terraform-linters/setup-tflint@v4 + with: + tflint_version: v0.51.1 + - name: Terraform Lint + run: make lint - name: Terraform Validate run: make validate diff --git a/.tflint.hcl b/.tflint.hcl new file mode 100644 index 00000000..24dcf262 --- /dev/null +++ b/.tflint.hcl @@ -0,0 +1,10 @@ +plugin "terraform" { + enabled = true + preset = "recommended" +} + +plugin "google" { + enabled = true + version = "0.29.0" + source = "github.com/terraform-linters/tflint-ruleset-google" +} diff --git a/Makefile b/Makefile index 309af4fc..7d3b7040 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,18 @@ TF_DIRS = $(patsubst %/main.tf, %, $(shell find . -type d -name .terraform -prune -o -name 'main.tf' -print)) VALIDATE_TF_DIRS = $(addprefix validate-,$(TF_DIRS)) +LINT_TF_DIRS = $(addprefix lint-,$(TF_DIRS)) +DOCS_TF_DIRS = $(addprefix docs-,$(TF_DIRS)) + +# Generate docs for a terraform directories +$(DOCS_TF_DIRS): docs-%: + @echo "Docs $*" + terraform-docs --config docs/.terraform-docs.yaml $* + terraform-docs --config docs/.terraform-docs-example.yaml $* # Generate docs .PHONY: docs -docs: - # terraform-docs --lockfile=false ./modules/base - terraform-docs --config docs/.terraform-docs.yaml . - terraform-docs --config docs/.terraform-docs-example.yaml . - terraform-docs --config docs/.terraform-docs.yaml ./examples/with-backstage - terraform-docs --config docs/.terraform-docs-example.yaml ./examples/with-backstage +docs: $(DOCS_TF_DIRS) + @echo "All docs generated" # Format all terraform files fmt: @@ -27,3 +31,16 @@ $(VALIDATE_TF_DIRS): validate-%: # Validate all terraform directories validate: $(VALIDATE_TF_DIRS) @echo "All validated" + +# Lint a terraform directories +$(LINT_TF_DIRS): lint-%: + @echo "Lint $*" + tflint --config "$(PWD)/.tflint.hcl" --chdir="$*" + +# Initialize tflint +lint-init: + tflint --init + +# Lint all terraform directories +lint: lint-init $(LINT_TF_DIRS) fmt-check + @echo "All linted" diff --git a/README.md b/README.md index 0e195466..d278ffc0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Humanitec Google Cloud Reference Architecture Implementation +> > TL;DR > >Skip the theory? Go [here](#how-to-spin-up-your-humanitec-google-cloud-reference-architecture-implementation) to spin up your Humanitec Google Cloud Reference Architecture Implementation. @@ -19,33 +20,34 @@ When McKinsey originally [published the reference architecture](https://youtu.be ![Google Cloud reference architecture Humanitec](docs/images/Reference-Architecture-Google-Cloud-Humanitec.png) -### Developer Control Plane +### Developer Control Plane This plane is the primary configuration layer and interaction point for the platform users. It harbors the following components: * A **Version Control System**. GitHub is a prominent example, but this can be any system that contains two types of repositories: - * Application Source Code - * Platform Source Code, e.g. using Terraform + * Application Source Code + * Platform Source Code, e.g. using Terraform * **Workload specifications**. The reference architecture uses [Score](https://developer.humanitec.com/score/overview/). * A **portal** for developers to interact with. It can be the Humanitec Portal, but you might also use [Backstage](https://backstage.io/) or any other portal on the market. -### Integration and Delivery Plane +### Integration and Delivery Plane This plane is about building and storing the image, creating app and infra configs from the abstractions provided by the developers, and deploying the final state. It’s where the domains of developers and platform engineers meet. This plane usually contains four different tools: + * A **CI pipeline**. It can be Github Actions or any CI tooling on the market. * The **image registry** holding your container images. Again, this can be any registry on the market. * An **orchestrator** which in our example, is the Humanitec Platform Orchestrator. * The **CD system**, which can be the Platform Orchestrator’s deployment pipeline capabilities — an external system triggered by the Orchestrator using a webhook, or a setup in tandem with GitOps operators like ArgoCD. -### Monitoring and Logging Plane +### Monitoring and Logging Plane The integration of monitoring and logging systems varies greatly depending on the system. This plane however is not a focus of the reference architecture. -### Security Plane +### Security Plane -The security plane of the reference architecture is focused on the secrets management system. The secrets manager stores configuration information such as database passwords, API keys, or TLS certificates needed by an Application at runtime. It allows the Platform Orchestrator to reference the secrets and inject them into the Workloads dynamically. You can learn more about secrets management and integration with other secrets management [here](https://developer.humanitec.com/platform-orchestrator/security/overview). +The security plane of the reference architecture is focused on the secrets management system. The secrets manager stores configuration information such as database passwords, API keys, or TLS certificates needed by an Application at runtime. It allows the Platform Orchestrator to reference the secrets and inject them into the Workloads dynamically. You can learn more about secrets management and integration with other secrets management [here](https://developer.humanitec.com/platform-orchestrator/security/overview). The reference architecture sample implementations use the secrets store attached to the Humanitec SaaS system. @@ -54,22 +56,19 @@ The reference architecture sample implementations use the secrets store attached This plane is where the actual infrastructure exists including clusters, databases, storage, or DNS services. The configuration of the Resources is managed by the Platform Orchestrator which dynamically creates app and infrastructure configurations with every deployment and creates, updates, or deletes dependent Resources as required. ## How to spin up your Humanitec Google Cloud Reference Architecture Implementation -This repo contains an implementation of part of the Humanitec Reference Architecture for an Internal Developer Platform. - -To install an implementation containing add-ons, follow the separate README. We currently feature these add-ons: -* [Base layer plus Backstage](examples/with-backstage/) +This repo contains an implementation of part of the Humanitec Reference Architecture for an Internal Developer Platform, including Backstage as optional Portal solution. This repo covers the base layer of the implementation for Google Cloud (GCP). By default, the following will be provisioned: -- VPC -- GKE Autopilot Cluster -- Google Service Account to access the cluster -- Ingress NGINX in the cluster -- Resource Definitions in Humanitec for: - - Kubernetes Cluster +* VPC +* GKE Autopilot Cluster +* Google Service Account to access the cluster +* Ingress NGINX in the cluster +* Resource Definitions in Humanitec for: + * Kubernetes Cluster ### Prerequisites @@ -99,13 +98,13 @@ This reference architecture implementation uses Terraform. You will need to do t For example: - ``` + ```shell export HUMANITEC_TOKEN="my-humanitec-api-token" ``` 5. Run terraform: - ``` + ```shell terraform init terraform plan terraform apply @@ -130,46 +129,90 @@ There are many other optional inputs that can be set. The full list is described Check for the existence of key elements of the reference architecture. This is a subset of all elements only. For a complete list of what was installed, review the Terraform code. 1. Set the `HUMANITEC_ORG` environment variable to the ID of your Humanitec Organization (must be all lowercase): -```bash -export HUMANITEC_ORG="my-humanitec-org" -``` + + ```bash + export HUMANITEC_ORG="my-humanitec-org" + ``` 2. Verify the existence of the Resource Definition for the GKE cluster in your Humanitec Organization: -```bash -curl -s https://api.humanitec.io/orgs/${HUMANITEC_ORG}/resources/defs/htc-ref-arch-cluster \ - --header "Authorization: Bearer ${HUMANITEC_TOKEN}" \ - | jq .id,.type -``` -This should output: -```bash -"htc-ref-arch-cluster" -"k8s-cluster" -``` + + ```bash + curl -s https://api.humanitec.io/orgs/${HUMANITEC_ORG}/resources/defs/htc-ref-arch-cluster \ + --header "Authorization: Bearer ${HUMANITEC_TOKEN}" \ + | jq .id,.type + ``` + + This should output: + + ```bash + "htc-ref-arch-cluster" + "k8s-cluster" + ``` 3. Verify the existence of the newly created GKE cluster: -```bash -gcloud container clusters list --filter "name=htc-ref-arch-cluster" -``` -This should output cluster data like this: -```bash -NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS -htc-ref-arch-cluster xx.xx.xx-gke.xx xx.xx.xx.xx n2d-standard-4 xx.xx.xx-gke.xx 3 RUNNING -``` + ```bash + gcloud container clusters list --filter "name=htc-ref-arch-cluster" + ``` + + This should output cluster data like this: + + ```bash + NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS + htc-ref-arch-cluster xx.xx.xx-gke.xx xx.xx.xx.xx n2d-standard-4 xx.xx.xx-gke.xx 3 RUNNING + ``` + +### Enable a portal (optional) + +#### Portal Prerequisites + +Backstage requires a GitHub connection, which in turn needs: + +* A GitHub organization and permission to create new repositories in it. Go to to create a new org (the "Free" option is fine). Note: is has to be an organization, a free account is not sufficient. +* Create a classic github personal access token with `repo`, `workflow`, `delete_repo` and `admin:org` scope [here](https://github.com/settings/tokens). +* Set the `GITHUB_TOKEN` environment variable to your token. + + ```shell + export GITHUB_TOKEN="my-github-token" + ``` + +* Set the `GITHUB_ORG_ID` environment variable to your GitHub organization ID. + + ```shell + export GITHUB_ORG_ID="my-github-org-id" + ``` + +* Install the GitHub App for Backstage into your GitHub organization + * Run `docker run --rm -it -e GITHUB_ORG_ID -v $(pwd):/pwd -p 127.0.0.1:3000:3000 ghcr.io/humanitec-architecture/create-gh-app` ([image source](https://github.com/humanitec-architecture/create-gh-app/)) and follow the instructions: + * “All repositories” ~> Install + * “Okay, […] was installed on the […] account.” ~> You can close the window and server. + +#### Portal Usage + +* Enable `with_backstage` inside your `terraform.tfvars` and configure the additional variables that a required for Backstage. +* Perform another `terraform apply` + +#### Verify portal setup + +* [Fetch the DNS entry](https://developer.humanitec.com/score/getting-started/get-dns/) of the Humanitec Application `backstage`, Environment `development`. +* Open the host in your browser. +* Click the "Create" button and scaffold your first application. ### Cleaning up Once you are finished with the reference architecture, you can remove all provisioned infrastructure and the resource definitions created in Humanitec with the following: -1. Ensure you are (still) logged in with `gcloud`. +1. Delete all Humanitec Applications scaffolded using the Portal, if you used one, but not the `backstage` app itself. -2. Ensure you still have the `HUMANITEC_TOKEN` environment variable set to an appropriate Humanitec API token with the `Administrator` role on the Humanitec Organization. +2. Ensure you are (still) logged in with `gcloud`. + +3. Ensure you still have the `HUMANITEC_TOKEN` environment variable set to an appropriate Humanitec API token with the `Administrator` role on the Humanitec Organization. You can verify this in the UI if you log in with an Administrator user and go to Resource Management, and check the "Usage" of each resource definition with the prefix set in `humanitec_prefix` - by default this is `htc-ref-arch-`. -3. Run terraform: +4. Run terraform: - ``` + ```shell terraform destroy ``` @@ -181,7 +224,17 @@ Once you are finished with the reference architecture, you can remove all provis | Name | Version | |------|---------| | terraform | >= 1.3.0 | +| github | ~> 5.38 | | google | ~> 5.1 | +| helm | ~> 2.12 | +| humanitec | ~> 1.0 | +| kubernetes | ~> 2.25 | +| random | ~> 3.5 | + +### Providers + +| Name | Version | +|------|---------| | humanitec | ~> 1.0 | ### Modules @@ -189,22 +242,37 @@ Once you are finished with the reference architecture, you can remove all provis | Name | Source | Version | |------|--------|---------| | base | ./modules/base | n/a | +| github | ./modules/github | n/a | +| github\_app | github.com/humanitec-architecture/shared-terraform-modules | v2024-06-12//modules/github-app | +| portal\_backstage | ./modules/portal-backstage | n/a | + +### Resources + +| Name | Type | +|------|------| +| [humanitec_service_user_token.deployer](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/service_user_token) | resource | +| [humanitec_user.deployer](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/user) | resource | ### Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| humanitec\_org\_id | ID of the Humanitec Organization to associate resources with. | `string` | n/a | yes | +| gar\_repository\_location | Location of the Google Artifact Registry repository, | `string` | n/a | yes | | project\_id | GCP Project ID to provision resources in. | `string` | n/a | yes | | region | GCP Region to provision resources in. | `string` | n/a | yes | | environment | The environment to associate the reference architecture with. | `string` | `null` | no | | environment\_type | The environment type to associate the reference architecture with. | `string` | `"development"` | no | +| gar\_repository\_id | Google Artifact Registry repository ID. | `string` | `"htc-ref-arch"` | no | +| github\_org\_id | GitHub org id (required for Backstage) | `string` | `null` | no | +| humanitec\_org\_id | Humanitec Organization ID (required for Backstage) | `string` | `null` | no | | humanitec\_prefix | A prefix that will be attached to all IDs created in Humanitec. | `string` | `"htc-ref-arch-"` | no | +| with\_backstage | Deploy Backstage | `bool` | `false` | no | ## Learn more Expand your knowledge by heading over to our learning path, and discover how to: + * Deploy the Humanitec reference architecture using a cloud provider of your choice * Deploy and manage Applications using the Humanitec Platform Orchestrator and Score * Provision additional Resources and connect to them @@ -227,5 +295,3 @@ Expand your knowledge by heading over to our learning path, and discover how to: * [Resource management theory](https://developer.humanitec.com/training/master-your-internal-developer-platform/resource-management-theory/) * [Tutorial: Provision a Redis cluster on AWS using Terraform](https://developer.humanitec.com/training/master-your-internal-developer-platform/provision-redis-aws/) * [Tutorial: Update Resource Definitions for related Applications](https://developer.humanitec.com/training/master-your-internal-developer-platform/update-resource-definitions-for-related-applications/) - - diff --git a/examples/with-backstage/README.md b/examples/with-backstage/README.md deleted file mode 100644 index c59dfa17..00000000 --- a/examples/with-backstage/README.md +++ /dev/null @@ -1,142 +0,0 @@ -# GCP reference architecture with Backstage - -Provisions the GCP reference architecture connected to Humanitec and installs Backstage. - -## Prerequisites - -* The same prerequisites as the [base reference architecture](../../README.md#prerequisites), plus the following items. -* A GitHub organization and permission to create new repositories in it. Go to https://github.com/account/organizations/new to create a new org (the "Free" option is fine). Note: is has to be an organization, a free account is not sufficient. -* Create a classic github personal access token with `repo`, `workflow`, `delete_repo` and `admin:org` scope [here](https://github.com/settings/tokens). -* Set the `GITHUB_TOKEN` environment variable to your token. - ``` - export GITHUB_TOKEN="my-github-token" - ``` -* Set the `GITHUB_ORG_ID` environment variable to your GitHub organization ID. - ``` - export GITHUB_ORG_ID="my-github-org-id" - ``` -* [Node.js](https://nodejs.org) installed locally. -* Install the GitHub App for Backstage into your GitHub organization using `node create-gh-app/index.js`. Follow the instructions. - * “All repositories” ~> Install - * “Okay, […] was installed on the […] account.” ~> You can close the window and server. - -## Usage - -Follow the same steps as for the [base layer](../../README.md#usage), applying these modifications: -* Execute `cd ./examples/with-backstage` after cloning the repo. Execute all subsequent commands in this directory. -* In particular, use the `./examples/with-backstage/terraform.tfvars.example` file as the basis for your `terraform.tfvars` file. It defines additional variables needed to setup and configure Backstage. - -## Verify your result - -Check for the existence of key elements of the backstage module. This is a subset of all elements only. For a complete list of what was installed, review the Terraform code. - -1. Perform the [verification steps of the base installation](../../README.md) if you have not already done so. -2. Verify the existence of the Backstage Application in your Humanitec Organization: - ``` - curl -s https://api.humanitec.io/orgs/${HUMANITEC_ORG}/apps/backstage \ - --header "Authorization: Bearer ${HUMANITEC_TOKEN}" - ``` - This should output a JSON formatted representation of the Application like so: - ``` - {"id":"backstage","name":"backstage","created_at":"2023-10-02T13:44:27Z","created_by":"s-d3e94a0e-8b53-29f9-b666-27548b7e06e0","envs":[{"id":"development","name":"Development","type":"development"}]} - ``` - You can also check for the Application in the [Humanitec Platform Orchestrator UI](https://app.humanitec.io). - -3. Connect to your GKE cluster via `kubectl`. See the [GKE documentation](https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl) or use this command: - ``` - gcloud container clusters get-credentials htc-ref-arch-cluster --location - ``` -4. Get the elements in the newly created Kubernetes namespace: - ``` - kubectl get all -n backstage-development - ``` - You should see - - a `deployment`, `replicaset`, running `pod`, and `service` for Backstage - - a `statefulset`, running `pod`, and `service` for PostgreSQL database used by Backstage. - - Note: it may take up to ten minutes after the `terraform apply` completed until you actually see those resources. The Backstage application needs to built and deployed via a GitHub action out of the newly created repository in your GitHub organization. - - -## Cleaning up - -Once you are finished with the reference architecture, you can remove all provisioned infrastructure and the resource definitions created in Humanitec with the following: - -1. Delete all Humanitec applications scaffolded using Backstage, but not the `backstage` app itself. - -2. Follow the [base reference architecture cleanup instructions](../../README.md#cleaning-up). - -## Terraform docs - - -### Requirements - -| Name | Version | -|------|---------| -| terraform | >= 1.3.0 | -| github | ~> 5.38 | -| google | ~> 5.1 | -| humanitec | ~> 1.0 | -| random | ~> 3.5 | - -### Providers - -| Name | Version | -|------|---------| -| github | ~> 5.38 | -| google | ~> 5.1 | -| humanitec | ~> 1.0 | -| random | ~> 3.5 | - -### Modules - -| Name | Source | Version | -|------|--------|---------| -| backstage\_mysql | git::https://github.com/humanitec-architecture/resource-packs-in-cluster.git//humanitec-resource-defs/mysql/basic | n/a | -| backstage\_postgres | git::https://github.com/humanitec-architecture/resource-packs-in-cluster.git//humanitec-resource-defs/postgres/basic | n/a | -| base | ../../modules/base | n/a | -| gh\_oidc | terraform-google-modules/github-actions-runners/google//modules/gh-oidc | ~> 3.1 | - -### Resources - -| Name | Type | -|------|------| -| [github_actions_organization_secret.backstage_humanitec_token](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_secret) | resource | -| [github_actions_organization_variable.backstage_cloud_provider](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | -| [github_actions_organization_variable.backstage_gcp_gar_host](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | -| [github_actions_organization_variable.backstage_gcp_gar_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | -| [github_actions_organization_variable.backstage_gcp_service_account](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | -| [github_actions_organization_variable.backstage_gcp_workload_identity_provider](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | -| [github_actions_organization_variable.backstage_humanitec_org_id](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | -| [github_repository.backstage](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource | -| [google_artifact_registry_repository_iam_member.gha_gar_containers_writer](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/artifact_registry_repository_iam_member) | resource | -| [google_service_account.sa](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource | -| [humanitec_application.backstage](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/application) | resource | -| [humanitec_resource_definition_criteria.backstage_mysql](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | -| [humanitec_resource_definition_criteria.backstage_postgres](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | -| [humanitec_value.app_config_backend_auth_keys](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | -| [humanitec_value.backstage_cloud_provider](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | -| [humanitec_value.backstage_github_app_client_id](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | -| [humanitec_value.backstage_github_app_client_secret](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | -| [humanitec_value.backstage_github_app_id](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | -| [humanitec_value.backstage_github_app_private_key](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | -| [humanitec_value.backstage_github_app_webhook_secret](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | -| [humanitec_value.backstage_github_org_id](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | -| [humanitec_value.backstage_humanitec_org](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | -| [humanitec_value.backstage_humanitec_token](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/value) | resource | -| [random_bytes.backstage_service_to_service_auth_key](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/bytes) | resource | -| [random_string.oidc_suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | - -### Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| gar\_repository\_location | Location of the Google Artifact Registry repository, | `string` | n/a | yes | -| github\_org\_id | GitHub org id | `string` | n/a | yes | -| humanitec\_ci\_service\_user\_token | Humanitec CI Service User Token | `string` | n/a | yes | -| humanitec\_org\_id | Humanitec Organization ID | `string` | n/a | yes | -| project\_id | GCP Project ID to provision resources in. | `string` | n/a | yes | -| region | GCP Region to provision resources in. | `string` | n/a | yes | -| environment | The environment to associate the reference architecture with. | `string` | `null` | no | -| environment\_type | The environment type to associate the reference architecture with. | `string` | `"development"` | no | -| humanitec\_prefix | A prefix that will be attached to all IDs created in Humanitec. | `string` | `"htc-ref-arch-"` | no | - diff --git a/examples/with-backstage/backstage-humanitec.tf b/examples/with-backstage/backstage-humanitec.tf deleted file mode 100644 index 361896e7..00000000 --- a/examples/with-backstage/backstage-humanitec.tf +++ /dev/null @@ -1,128 +0,0 @@ -resource "humanitec_application" "backstage" { - id = "backstage" - name = "backstage" -} - -# Configure required values for backstage - -resource "humanitec_value" "backstage_github_org_id" { - app_id = humanitec_application.backstage.id - key = "GITHUB_ORG_ID" - description = "" - value = var.github_org_id - is_secret = false -} - -resource "humanitec_value" "backstage_github_app_id" { - app_id = humanitec_application.backstage.id - key = "GITHUB_APP_ID" - description = "" - value = local.github_app_id - is_secret = false -} - -resource "humanitec_value" "backstage_github_app_client_id" { - app_id = humanitec_application.backstage.id - key = "GITHUB_APP_CLIENT_ID" - description = "" - value = local.github_app_client_id - is_secret = true -} - -resource "humanitec_value" "backstage_github_app_client_secret" { - app_id = humanitec_application.backstage.id - key = "GITHUB_APP_CLIENT_SECRET" - description = "" - value = local.github_app_client_secret - is_secret = true -} - -resource "humanitec_value" "backstage_github_app_private_key" { - app_id = humanitec_application.backstage.id - key = "GITHUB_APP_PRIVATE_KEY" - description = "" - value = indent(2, local.github_app_private_key) - is_secret = true -} - -resource "humanitec_value" "backstage_github_app_webhook_secret" { - app_id = humanitec_application.backstage.id - key = "GITHUB_APP_WEBHOOK_SECRET" - description = "" - value = local.github_webhook_secret - is_secret = true -} - -resource "humanitec_value" "backstage_humanitec_org" { - app_id = humanitec_application.backstage.id - key = "HUMANITEC_ORG_ID" - description = "" - value = var.humanitec_org_id - is_secret = false -} - -resource "humanitec_value" "backstage_humanitec_token" { - app_id = humanitec_application.backstage.id - key = "HUMANITEC_TOKEN" - description = "" - value = var.humanitec_ci_service_user_token - is_secret = true -} - -resource "humanitec_value" "backstage_cloud_provider" { - app_id = humanitec_application.backstage.id - key = "CLOUD_PROVIDER" - description = "" - value = "gcp" - is_secret = false -} - -resource "random_bytes" "backstage_service_to_service_auth_key" { - length = 24 -} - -resource "humanitec_value" "app_config_backend_auth_keys" { - app_id = humanitec_application.backstage.id - key = "APP_CONFIG_backend_auth_keys" - description = "Backstage service-to-service-auth keys" - value = jsonencode([{ - secret = random_bytes.backstage_service_to_service_auth_key.base64 - }]) - is_secret = true -} - -# Configure required resources for backstage - -locals { - res_def_prefix = "backstage-" -} - -# in-cluster postgres - -module "backstage_postgres" { - source = "git::https://github.com/humanitec-architecture/resource-packs-in-cluster.git//humanitec-resource-defs/postgres/basic" - - prefix = local.res_def_prefix -} - -resource "humanitec_resource_definition_criteria" "backstage_postgres" { - resource_definition_id = module.backstage_postgres.id - app_id = humanitec_application.backstage.id - - force_delete = true -} - -# Configure required resources for scaffolded apps - -# in-cluster mysql - -module "backstage_mysql" { - source = "git::https://github.com/humanitec-architecture/resource-packs-in-cluster.git//humanitec-resource-defs/mysql/basic" - - prefix = local.res_def_prefix -} - -resource "humanitec_resource_definition_criteria" "backstage_mysql" { - resource_definition_id = module.backstage_mysql.id - env_type = var.environment -} diff --git a/examples/with-backstage/create-gh-app/index.js b/examples/with-backstage/create-gh-app/index.js deleted file mode 100644 index 553c0731..00000000 --- a/examples/with-backstage/create-gh-app/index.js +++ /dev/null @@ -1,153 +0,0 @@ -// Small CLI tool to create a GitHub App for Backstage -// -// Heavily inspired by https://github.com/backstage/backstage/blob/master/packages/cli/src/commands/create-github-app/ - -const http = require('http'); -const crypto = require('crypto'); -const fs = require('fs/promises') - -const hostname = '127.0.0.1'; -const port = 3000; - -const FORM_PAGE = ` - - -
- - -
- - - -`; - - -let baseUrl; - - -const webhookId = crypto -.randomBytes(15) -.toString('base64') -.replace(/[\+\/]/g, ''); - -const webhookUrl = `https://smee.io/${webhookId}`; - -const handleIndex = (req, res, GITHUB_ORG_ID) => { - const encodedOrg = encodeURIComponent(GITHUB_ORG_ID); - const actionUrl = `https://github.com/organizations/${encodedOrg}/settings/apps/new`; - - - res.statusCode = 200; - const manifest = { - default_events: ['create', 'delete', 'push', 'repository'], - default_permissions: { - members: 'read', - administration: 'write', - contents: 'write', - metadata: 'read', - pull_requests: 'write', - issues: 'write', - workflows: 'write', - checks: 'read', - actions_variables: 'write', - secrets: 'write', - environments: 'write', - }, - name: `backstage-${GITHUB_ORG_ID}`, - url: 'https://backstage.io', - description: 'GitHub App for Backstage', - public: false, - redirect_url: `${baseUrl}/callback`, - hook_attributes: { - url: webhookUrl, - active: false, - }, - }; - - const manifestJson = JSON.stringify(manifest).replace(/\"/g, '"'); - - let body = FORM_PAGE; - body = body.replace('MANIFEST_JSON', manifestJson); - body = body.replace('ACTION_URL', actionUrl); - - res.setHeader('content-type', 'text/html'); - res.end(body); -} - - -const writeConfigFile = async (data, webhookUrl) => { - const fileName = `github-app-credentials.json`; - const content = JSON.stringify({ - name: data.name, - slug: data.slug, - appId: data.id, - webhookUrl: webhookUrl, - clientId: data.client_id, - clientSecret: data.client_secret, - webhookSecret: data.webhook_secret, - privateKey: data.pem, - }, null, 2) - - await fs.writeFile(fileName, content); - - console.log(`Created ${fileName}, you can close the server now.`) -} - -const handleCallback = async (req, res) => { - const url = new URL(req.url, `http://${req.headers.host}`); - const conversionRes = await fetch(`https://api.github.com/app-manifests/${encodeURIComponent(url.searchParams.get('code'))}/conversions`, { - method: 'POST', - }); - - if (conversionRes.status !== 201) { - const body = await conversionRes.text(); - res.statusCode = conversionRes.status; - res.end(body); - } - - const data = await conversionRes.json(); - - await writeConfigFile(data, webhookUrl); - - res.writeHead(302, { Location: `${data.html_url}/installations/new` }); - res.end(); -} - -if (process.env.STUB_FILE === '1') { - writeConfigFile({ - name: 'stub', - slug: 'stub', - id: 'stub', - client_id: 'stub', - client_secret: 'stub', - webhook_secret: 'stub', - pem: 'stub', - }, 'https://smee.io/stub'); - - return; -} - -const GITHUB_ORG_ID = process.env.GITHUB_ORG_ID; -if (!GITHUB_ORG_ID) { - console.error('Please export GITHUB_ORG_ID'); - process.exit(1); -} - -const server = http.createServer((req, res) => { - if (req.url === '/') { - handleIndex(req, res, GITHUB_ORG_ID); - } else if (req.url.startsWith('/callback?')) { - handleCallback(req, res); - } else { - res.statusCode = 404; - res.end('Not found, url: ' + req.url); - } -}); - -server.listen(port, hostname, () => { - baseUrl = `http://${hostname}:${port}`; - - console.log(`Open ${baseUrl}`); -}); diff --git a/examples/with-backstage/main.tf b/examples/with-backstage/main.tf deleted file mode 100644 index 6702b18c..00000000 --- a/examples/with-backstage/main.tf +++ /dev/null @@ -1,20 +0,0 @@ -# GCP reference architecture - -locals { - repository_id = "htc-ref-arch" - repository_host = "${var.gar_repository_location}-docker.pkg.dev" - repository_name = "${local.repository_host}/${var.project_id}/${local.repository_id}" -} - -module "base" { - source = "../../modules/base" - project_id = var.project_id - region = var.region - humanitec_org_id = var.humanitec_org_id - humanitec_prefix = var.humanitec_prefix - environment = var.environment - environment_type = var.environment_type - - gar_repository_id = local.repository_id - gar_repository_location = var.gar_repository_location -} diff --git a/examples/with-backstage/terraform.tfvars.example b/examples/with-backstage/terraform.tfvars.example deleted file mode 100644 index d457ba6e..00000000 --- a/examples/with-backstage/terraform.tfvars.example +++ /dev/null @@ -1,27 +0,0 @@ - -# The environment to associate the reference architecture with. -environment = "" - -# The environment type to associate the reference architecture with. -environment_type = "development" - -# Location of the Google Artifact Registry repository, -gar_repository_location = "" - -# GitHub org id -github_org_id = "" - -# Humanitec CI Service User Token -humanitec_ci_service_user_token = "" - -# Humanitec Organization ID -humanitec_org_id = "" - -# A prefix that will be attached to all IDs created in Humanitec. -humanitec_prefix = "htc-ref-arch-" - -# GCP Project ID to provision resources in. -project_id = "" - -# GCP Region to provision resources in. -region = "" \ No newline at end of file diff --git a/examples/with-backstage/variables.tf b/examples/with-backstage/variables.tf deleted file mode 100644 index c5b8d082..00000000 --- a/examples/with-backstage/variables.tf +++ /dev/null @@ -1,57 +0,0 @@ -########################################## -# REQUIRED INPUTS -########################################## - -variable "project_id" { - type = string - description = "GCP Project ID to provision resources in." -} - - -variable "region" { - type = string - description = "GCP Region to provision resources in." -} - -variable "gar_repository_location" { - type = string - description = "Location of the Google Artifact Registry repository," -} - -variable "github_org_id" { - description = "GitHub org id" - type = string -} - -variable "humanitec_org_id" { - description = "Humanitec Organization ID" - type = string -} - -variable "humanitec_ci_service_user_token" { - description = "Humanitec CI Service User Token" - type = string - sensitive = true -} - -########################################## -# OPTIONAL INPUTS -########################################## - -variable "environment" { - type = string - description = "The environment to associate the reference architecture with." - default = null -} - -variable "environment_type" { - type = string - description = "The environment type to associate the reference architecture with." - default = "development" -} - -variable "humanitec_prefix" { - type = string - description = "A prefix that will be attached to all IDs created in Humanitec." - default = "htc-ref-arch-" -} diff --git a/main.tf b/main.tf index 9b7eb99c..646e555f 100644 --- a/main.tf +++ b/main.tf @@ -1,33 +1,81 @@ -terraform { - required_providers { - google = { - source = "hashicorp/google" - version = "~> 5.1" - } - humanitec = { - source = "humanitec/humanitec" - version = "~> 1.0" - } - } - required_version = ">= 1.3.0" -} - -provider "google" { - project = var.project_id -} - -provider "humanitec" { - org_id = var.humanitec_org_id -} - - +# GCP reference architecture module "base" { source = "./modules/base" project_id = var.project_id region = var.region - humanitec_org_id = var.humanitec_org_id humanitec_prefix = var.humanitec_prefix environment = var.environment environment_type = var.environment_type + + gar_repository_id = var.gar_repository_id + gar_repository_location = var.gar_repository_location +} + +# User used for scaffolding and deploying apps + +resource "humanitec_user" "deployer" { + count = var.with_backstage ? 1 : 0 + + name = "deployer" + role = "administrator" + type = "service" +} + +resource "humanitec_service_user_token" "deployer" { + count = var.with_backstage ? 1 : 0 + + id = "deployer" + user_id = humanitec_user.deployer[0].id + description = "Used by scaffolding and deploying" +} + + +module "github" { + count = var.with_backstage ? 1 : 0 + + source = "./modules/github" + + humanitec_org_id = var.humanitec_org_id + humanitec_ci_service_user_token = humanitec_service_user_token.deployer[0].token + project_id = var.project_id + github_org_id = var.github_org_id + gar_repository_id = var.gar_repository_id + gar_repository_location = var.gar_repository_location + + depends_on = [module.base] +} + +# Configure GitHub variables & secrets for Backstage itself and for all scaffolded apps + +locals { + github_app_credentials_file = "github-app-credentials.json" +} + +module "github_app" { + count = var.with_backstage ? 1 : 0 + + source = "github.com/humanitec-architecture/shared-terraform-modules?ref=v2024-06-12//modules/github-app" + + credentials_file = "${path.module}/${local.github_app_credentials_file}" +} + +# Deploy Backstage as Portal + +module "portal_backstage" { + count = var.with_backstage ? 1 : 0 + + source = "./modules/portal-backstage" + + humanitec_org_id = var.humanitec_org_id + humanitec_ci_service_user_token = humanitec_service_user_token.deployer[0].token + + github_org_id = var.github_org_id + github_app_client_id = module.github_app[0].client_id + github_app_client_secret = module.github_app[0].client_secret + github_app_id = module.github_app[0].app_id + github_app_private_key = module.github_app[0].private_key + github_webhook_secret = module.github_app[0].webhook_secret + + depends_on = [module.github] } diff --git a/modules/base/README.md b/modules/base/README.md new file mode 100644 index 00000000..d4b132b8 --- /dev/null +++ b/modules/base/README.md @@ -0,0 +1,55 @@ + +### Requirements + +| Name | Version | +|------|---------| +| terraform | >= 1.3.0 | +| google | ~> 5.1 | +| humanitec | ~> 1.0 | + +### Providers + +| Name | Version | +|------|---------| +| google | ~> 5.1 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| k8s | ../gke | n/a | +| network | ../network | n/a | +| res\_defs | ../htc_res_defs | n/a | + +### Resources + +| Name | Type | +|------|------| +| [google_project_service.apis](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/project_service) | resource | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| environment | The environment to associate the reference architecture with. | `string` | n/a | yes | +| environment\_type | The environment type to associate the reference architecture with. | `string` | n/a | yes | +| project\_id | GCP Project ID to provision resources in. | `string` | n/a | yes | +| region | GCP Region to provision resources in. | `string` | n/a | yes | +| gar\_repository\_id | ID of the Google Artifact Registry repository (not created if empty). | `string` | `null` | no | +| gar\_repository\_location | Location of the Google Artifact Registry repository (required when gar\_repository\_id is set). | `string` | `null` | no | +| gke\_autopilot | Whether GKE Autopilot should be used | `bool` | `true` | no | +| gke\_cluster\_name | The name of the GKE Cluster. Must be unique within the project. | `string` | `"htc-ref-arch-cluster"` | no | +| gke\_subnet\_name | The name of the subnet to allocate IPs for the GKE Cluster from. If vpc\_subnet is set, this must be updated. | `string` | `"htc-ref-arch-subnet"` | no | +| humanitec\_prefix | A prefix that will be attached to all IDs created in Humanitec. | `string` | `""` | no | +| vpc\_description | VPC Description | `string` | `"VPC for Humanitec Reference Architecture Implementation for GCP. https://github.com/humanitec-architecture/reference-archietcture-gcp"` | no | +| vpc\_name | VPC Name | `string` | `"htc-ref-arch-vpc"` | no | +| vpc\_subnets | List of VPC Subnets |
list(object({
name = string
description = string
ip_cidr_range = string
purpose = optional(string)
role = optional(string)
region = optional(string)
private_ip_google_access = optional(bool)
secondary_ip_range = optional(list(object({
range_name = string
ip_cidr_range = string
})))
}))
|
[
{
"description": "Subnet that hosts resources provisioned for the Humanitec Reference Architecture Implementation for GCP. https://github.com/humanitec-architecture/reference-archietcture-gcp",
"ip_cidr_range": "10.128.0.0/20",
"name": "htc-ref-arch-subnet"
}
]
| no | + +### Outputs + +| Name | Description | +|------|-------------| +| gar\_repository\_id | Google Artifact Registry repository id (if created). | +| gke\_ca\_certificate | GKE cluster CA certificate. | +| gke\_endpoint | GKE cluster endpoint. | + \ No newline at end of file diff --git a/modules/base/outputs.tf b/modules/base/outputs.tf index 0afeea37..989ac87b 100644 --- a/modules/base/outputs.tf +++ b/modules/base/outputs.tf @@ -2,3 +2,13 @@ output "gar_repository_id" { description = "Google Artifact Registry repository id (if created)." value = module.k8s.gar_repository_id } + +output "gke_endpoint" { + description = "GKE cluster endpoint." + value = module.k8s.cluster_endpoint +} + +output "gke_ca_certificate" { + description = "GKE cluster CA certificate." + value = module.k8s.cluster_ca_certificate +} diff --git a/modules/base/providers.tf b/modules/base/providers.tf index a65bf221..9c3aaeed 100644 --- a/modules/base/providers.tf +++ b/modules/base/providers.tf @@ -1,10 +1,13 @@ terraform { required_providers { humanitec = { - source = "humanitec/humanitec" + source = "humanitec/humanitec" + version = "~> 1.0" } google = { - source = "hashicorp/google" + source = "hashicorp/google" + version = "~> 5.1" } } -} \ No newline at end of file + required_version = ">= 1.3.0" +} diff --git a/modules/base/terraform.tfvars.example b/modules/base/terraform.tfvars.example new file mode 100644 index 00000000..c3a72d00 --- /dev/null +++ b/modules/base/terraform.tfvars.example @@ -0,0 +1,45 @@ + +# The environment to associate the reference architecture with. +environment = "" + +# The environment type to associate the reference architecture with. +environment_type = "" + +# ID of the Google Artifact Registry repository (not created if empty). +gar_repository_id = "" + +# Location of the Google Artifact Registry repository (required when gar_repository_id is set). +gar_repository_location = "" + +# Whether GKE Autopilot should be used +gke_autopilot = true + +# The name of the GKE Cluster. Must be unique within the project. +gke_cluster_name = "htc-ref-arch-cluster" + +# The name of the subnet to allocate IPs for the GKE Cluster from. If vpc_subnet is set, this must be updated. +gke_subnet_name = "htc-ref-arch-subnet" + +# A prefix that will be attached to all IDs created in Humanitec. +humanitec_prefix = "" + +# GCP Project ID to provision resources in. +project_id = "" + +# GCP Region to provision resources in. +region = "" + +# VPC Description +vpc_description = "VPC for Humanitec Reference Architecture Implementation for GCP. https://github.com/humanitec-architecture/reference-archietcture-gcp" + +# VPC Name +vpc_name = "htc-ref-arch-vpc" + +# List of VPC Subnets +vpc_subnets = [ + { + "description": "Subnet that hosts resources provisioned for the Humanitec Reference Architecture Implementation for GCP. https://github.com/humanitec-architecture/reference-archietcture-gcp", + "ip_cidr_range": "10.128.0.0/20", + "name": "htc-ref-arch-subnet" + } +] \ No newline at end of file diff --git a/modules/base/variables.tf b/modules/base/variables.tf index b5748640..f6259d99 100644 --- a/modules/base/variables.tf +++ b/modules/base/variables.tf @@ -13,12 +13,6 @@ variable "region" { description = "GCP Region to provision resources in." } - -variable "humanitec_org_id" { - type = string - description = "ID of the Humanitec Organization to associate resources with." -} - ########################################## # OPTIONAL INPUTS ########################################## diff --git a/modules/github/README.md b/modules/github/README.md new file mode 100644 index 00000000..827d61c8 --- /dev/null +++ b/modules/github/README.md @@ -0,0 +1,50 @@ + +### Requirements + +| Name | Version | +|------|---------| +| terraform | >= 1.3.0 | +| github | ~> 5.38 | +| google | ~> 5.1 | +| random | ~> 3.5 | + +### Providers + +| Name | Version | +|------|---------| +| github | ~> 5.38 | +| google | ~> 5.1 | +| random | ~> 3.5 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| gh\_oidc | terraform-google-modules/github-actions-runners/google//modules/gh-oidc | ~> 3.1 | + +### Resources + +| Name | Type | +|------|------| +| [github_actions_organization_secret.backstage_humanitec_token](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_secret) | resource | +| [github_actions_organization_variable.backstage_cloud_provider](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | +| [github_actions_organization_variable.backstage_gcp_gar_host](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | +| [github_actions_organization_variable.backstage_gcp_gar_name](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | +| [github_actions_organization_variable.backstage_gcp_service_account](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | +| [github_actions_organization_variable.backstage_gcp_workload_identity_provider](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | +| [github_actions_organization_variable.backstage_humanitec_org_id](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | +| [google_artifact_registry_repository_iam_member.gha_gar_containers_writer](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/artifact_registry_repository_iam_member) | resource | +| [google_service_account.sa](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/service_account) | resource | +| [random_string.oidc_suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| gar\_repository\_id | Google Artifact Registry repository ID. | `string` | n/a | yes | +| gar\_repository\_location | Location of the Google Artifact Registry repository. | `string` | n/a | yes | +| github\_org\_id | GitHub org id | `string` | n/a | yes | +| humanitec\_ci\_service\_user\_token | Humanitec CI Service User Token | `string` | n/a | yes | +| humanitec\_org\_id | Humanitec Organization ID | `string` | n/a | yes | +| project\_id | GCP Project ID to provision resources in. | `string` | n/a | yes | + \ No newline at end of file diff --git a/examples/with-backstage/gcp-github.tf b/modules/github/gcp.tf similarity index 94% rename from examples/with-backstage/gcp-github.tf rename to modules/github/gcp.tf index aea1cf76..216df633 100644 --- a/examples/with-backstage/gcp-github.tf +++ b/modules/github/gcp.tf @@ -1,7 +1,5 @@ locals { service_account_name = "htc-ref-arch-gha-gar-push" - name = "htc-ref-arch" - cloud_provider = "gcp" } resource "random_string" "oidc_suffix" { @@ -45,7 +43,7 @@ resource "google_service_account" "sa" { resource "google_artifact_registry_repository_iam_member" "gha_gar_containers_writer" { project = var.project_id location = var.gar_repository_location - repository = module.base.gar_repository_id + repository = var.gar_repository_id role = "roles/artifactregistry.writer" member = "serviceAccount:${google_service_account.sa.email}" } diff --git a/examples/with-backstage/backstage-github.tf b/modules/github/main.tf similarity index 52% rename from examples/with-backstage/backstage-github.tf rename to modules/github/main.tf index d15b933d..1c1cc30c 100644 --- a/examples/with-backstage/backstage-github.tf +++ b/modules/github/main.tf @@ -1,23 +1,16 @@ -# Configure GitHub variables & secrets for Backstage itself and for all scaffolded apps - locals { - github_app_credentials_file = "github-app-credentials.json" - github_app_credentials = jsondecode(file("${path.module}/${local.github_app_credentials_file}")) - github_app_id = local.github_app_credentials["appId"] - github_app_client_id = local.github_app_credentials["clientId"] - github_app_client_secret = local.github_app_credentials["clientSecret"] - github_app_private_key = local.github_app_credentials["privateKey"] - github_webhook_secret = local.github_app_credentials["webhookSecret"] -} + cloud_provider = "gcp" -locals { - backstage_repo = "backstage" + repository_host = "${var.gar_repository_location}-docker.pkg.dev" + repository_name = "${local.repository_host}/${var.project_id}/${var.gar_repository_id}" } +# Configure GitHub variables & secrets for all scaffolded apps + resource "github_actions_organization_variable" "backstage_cloud_provider" { variable_name = "CLOUD_PROVIDER" visibility = "all" - value = "gcp" + value = local.cloud_provider } resource "github_actions_organization_variable" "backstage_gcp_workload_identity_provider" { @@ -58,25 +51,3 @@ resource "github_actions_organization_secret" "backstage_humanitec_token" { visibility = "all" plaintext_value = var.humanitec_ci_service_user_token } - -# Backstage repository itself - -resource "github_repository" "backstage" { - name = local.backstage_repo - description = "Backstage" - - visibility = "public" - - template { - owner = "humanitec-architecture" - repository = "backstage" - } - - depends_on = [ - module.base, - module.gh_oidc, - humanitec_application.backstage, - humanitec_resource_definition_criteria.backstage_postgres, - github_actions_organization_secret.backstage_humanitec_token, - ] -} diff --git a/examples/with-backstage/provider.tf b/modules/github/providers.tf similarity index 56% rename from examples/with-backstage/provider.tf rename to modules/github/providers.tf index 302cf23c..f119e6aa 100644 --- a/examples/with-backstage/provider.tf +++ b/modules/github/providers.tf @@ -1,17 +1,13 @@ terraform { required_providers { - google = { - source = "hashicorp/google" - version = "~> 5.1" - } - humanitec = { - source = "humanitec/humanitec" - version = "~> 1.0" - } github = { source = "integrations/github" version = "~> 5.38" } + google = { + source = "hashicorp/google" + version = "~> 5.1" + } random = { source = "hashicorp/random" version = "~> 3.5" @@ -19,15 +15,3 @@ terraform { } required_version = ">= 1.3.0" } - -provider "humanitec" { - org_id = var.humanitec_org_id -} - -provider "github" { - owner = var.github_org_id -} - -provider "google" { - project = var.project_id -} diff --git a/modules/github/terraform.tfvars.example b/modules/github/terraform.tfvars.example new file mode 100644 index 00000000..a3742fe3 --- /dev/null +++ b/modules/github/terraform.tfvars.example @@ -0,0 +1,18 @@ + +# Google Artifact Registry repository ID. +gar_repository_id = "" + +# Location of the Google Artifact Registry repository. +gar_repository_location = "" + +# GitHub org id +github_org_id = "" + +# Humanitec CI Service User Token +humanitec_ci_service_user_token = "" + +# Humanitec Organization ID +humanitec_org_id = "" + +# GCP Project ID to provision resources in. +project_id = "" \ No newline at end of file diff --git a/modules/github/variables.tf b/modules/github/variables.tf new file mode 100644 index 00000000..1662000a --- /dev/null +++ b/modules/github/variables.tf @@ -0,0 +1,45 @@ +variable "project_id" { + type = string + description = "GCP Project ID to provision resources in." +} + +variable "gar_repository_id" { + type = string + description = "Google Artifact Registry repository ID." +} + +variable "gar_repository_location" { + type = string + description = "Location of the Google Artifact Registry repository." +} + +variable "humanitec_org_id" { + description = "Humanitec Organization ID" + type = string + + validation { + condition = var.humanitec_org_id != null + error_message = "Humanitec Organization ID must not be empty" + } +} + +variable "humanitec_ci_service_user_token" { + description = "Humanitec CI Service User Token" + type = string + sensitive = true + + validation { + condition = var.humanitec_ci_service_user_token != null + error_message = "Humanitec CI Service User Token must not be empty" + } +} + +variable "github_org_id" { + description = "GitHub org id" + type = string + + validation { + condition = var.github_org_id != null + error_message = "GitHub org id must not be empty" + } +} diff --git a/modules/gke/outputs.tf b/modules/gke/outputs.tf index 2ebc24d1..4c5e2074 100644 --- a/modules/gke/outputs.tf +++ b/modules/gke/outputs.tf @@ -29,6 +29,15 @@ output "cluster_name" { value = google_container_cluster.gke.name } +output "cluster_endpoint" { + value = google_container_cluster.gke.endpoint +} + +output "cluster_ca_certificate" { + description = "Base64 encoded certificate data required to communicate with the cluster" + value = base64decode(google_container_cluster.gke.master_auth.0.cluster_ca_certificate) +} + output "gar_repository_id" { value = var.gar_repository_id == null ? "" : google_artifact_registry_repository.repo[0].id } diff --git a/modules/gke/providers.tf b/modules/gke/providers.tf index 894a279d..8ebdb035 100644 --- a/modules/gke/providers.tf +++ b/modules/gke/providers.tf @@ -1,26 +1,17 @@ terraform { required_providers { - humanitec = { - source = "humanitec/humanitec" - } google = { - source = "hashicorp/google" + source = "hashicorp/google" + version = "~> 5.1" } helm = { - source = "hashicorp/helm" + source = "hashicorp/helm" + version = "~> 2.12" + } + humanitec = { + source = "humanitec/humanitec" + version = "~> 1.0" } - # http = { - # source = "hashicorp/http" - # } - } -} - -provider "helm" { - kubernetes { - host = "https://${google_container_cluster.gke.endpoint}" - token = data.google_client_config.default.access_token - cluster_ca_certificate = base64decode( - google_container_cluster.gke.master_auth.0.cluster_ca_certificate - ) } + required_version = ">= 1.3.0" } diff --git a/modules/htc_res_defs/README.md b/modules/htc_res_defs/README.md new file mode 100644 index 00000000..0869366e --- /dev/null +++ b/modules/htc_res_defs/README.md @@ -0,0 +1,46 @@ + +### Requirements + +| Name | Version | +|------|---------| +| terraform | >= 1.3.0 | +| humanitec | ~> 1.0 | + +### Providers + +| Name | Version | +|------|---------| +| humanitec | ~> 1.0 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| default\_mysql | github.com/humanitec-architecture/resource-packs-in-cluster | v2024-06-05//humanitec-resource-defs/mysql/basic | +| default\_postgres | github.com/humanitec-architecture/resource-packs-in-cluster | v2024-06-05//humanitec-resource-defs/postgres/basic | + +### Resources + +| Name | Type | +|------|------| +| [humanitec_resource_account.cluster_account](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_account) | resource | +| [humanitec_resource_definition.k8s_cluster](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition) | resource | +| [humanitec_resource_definition.k8s_namespace](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition) | resource | +| [humanitec_resource_definition_criteria.default_mysql](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | +| [humanitec_resource_definition_criteria.default_postgres](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | +| [humanitec_resource_definition_criteria.k8s_cluster](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | +| [humanitec_resource_definition_criteria.k8s_namespace](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| environment | The environment to use for matching criteria. | `string` | n/a | yes | +| environment\_type | The environment type to use for matching criteria. | `string` | n/a | yes | +| k8s\_cluster\_name | The name of the cluster. | `string` | n/a | yes | +| k8s\_credentials | The credentials used to establish a connection to the cluster. | `string` | n/a | yes | +| k8s\_loadbalancer | IP address or Host of the load balancer used by the ingress controller. | `string` | n/a | yes | +| k8s\_project\_id | The GCP Project the cluster is in. | `string` | n/a | yes | +| k8s\_region | The region the cluster is in. | `string` | n/a | yes | +| prefix | A prefix that will be attached to all IDs created in Humanitec. | `string` | `""` | no | + \ No newline at end of file diff --git a/modules/htc_res_defs/main.tf b/modules/htc_res_defs/main.tf index 70266179..23d75c6e 100644 --- a/modules/htc_res_defs/main.tf +++ b/modules/htc_res_defs/main.tf @@ -49,3 +49,28 @@ resource "humanitec_resource_definition_criteria" "k8s_namespace" { env_id = var.environment env_type = var.environment_type } + + +# in-cluster postgres + +module "default_postgres" { + source = "github.com/humanitec-architecture/resource-packs-in-cluster?ref=v2024-06-05//humanitec-resource-defs/postgres/basic" + + prefix = var.prefix +} + +resource "humanitec_resource_definition_criteria" "default_postgres" { + resource_definition_id = module.default_postgres.id + env_type = var.environment +} + +module "default_mysql" { + source = "github.com/humanitec-architecture/resource-packs-in-cluster?ref=v2024-06-05//humanitec-resource-defs/mysql/basic" + + prefix = var.prefix +} + +resource "humanitec_resource_definition_criteria" "default_mysql" { + resource_definition_id = module.default_mysql.id + env_type = var.environment +} diff --git a/modules/htc_res_defs/providers.tf b/modules/htc_res_defs/providers.tf index 5cd43507..59d13ba3 100644 --- a/modules/htc_res_defs/providers.tf +++ b/modules/htc_res_defs/providers.tf @@ -1,7 +1,9 @@ terraform { required_providers { humanitec = { - source = "humanitec/humanitec" + source = "humanitec/humanitec" + version = "~> 1.0" } } + required_version = ">= 1.3.0" } diff --git a/modules/htc_res_defs/terraform.tfvars.example b/modules/htc_res_defs/terraform.tfvars.example new file mode 100644 index 00000000..2600a8f6 --- /dev/null +++ b/modules/htc_res_defs/terraform.tfvars.example @@ -0,0 +1,24 @@ + +# The environment to use for matching criteria. +environment = "" + +# The environment type to use for matching criteria. +environment_type = "" + +# The name of the cluster. +k8s_cluster_name = "" + +# The credentials used to establish a connection to the cluster. +k8s_credentials = "" + +# IP address or Host of the load balancer used by the ingress controller. +k8s_loadbalancer = "" + +# The GCP Project the cluster is in. +k8s_project_id = "" + +# The region the cluster is in. +k8s_region = "" + +# A prefix that will be attached to all IDs created in Humanitec. +prefix = "" \ No newline at end of file diff --git a/modules/network/README.md b/modules/network/README.md new file mode 100644 index 00000000..3554b0d9 --- /dev/null +++ b/modules/network/README.md @@ -0,0 +1,43 @@ + +### Requirements + +| Name | Version | +|------|---------| +| terraform | >= 1.3.0 | +| google | ~> 5.1 | + +### Providers + +| Name | Version | +|------|---------| +| google | ~> 5.1 | + +### Resources + +| Name | Type | +|------|------| +| [google_compute_network.vpc_network](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_network) | resource | +| [google_compute_router.router](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_router) | resource | +| [google_compute_router_nat.router_nat](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_router_nat) | resource | +| [google_compute_subnetwork.vpc_subnetworks](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_subnetwork) | resource | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| project\_id | GCP Project ID | `string` | n/a | yes | +| region | GCP Region | `string` | n/a | yes | +| subnets | List of VPC Subnets |
list(object({
name = string
description = string
ip_cidr_range = string
purpose = optional(string)
role = optional(string)
region = optional(string)
private_ip_google_access = optional(bool)
secondary_ip_range = optional(list(object({
range_name = string
ip_cidr_range = string
})))
}))
| n/a | yes | +| vpc\_description | VPC Description | `string` | n/a | yes | +| vpc\_name | VPC Name | `string` | n/a | yes | + +### Outputs + +| Name | Description | +|------|-------------| +| subnet\_names | The subnet names | +| subnets | The created subnet resources | +| vpc\_id | n/a | +| vpc\_name | n/a | +| vpc\_self\_link | n/a | + \ No newline at end of file diff --git a/modules/network/main.tf b/modules/network/main.tf index 67d77cd5..207f0d35 100644 --- a/modules/network/main.tf +++ b/modules/network/main.tf @@ -1,9 +1,11 @@ terraform { required_providers { google = { - source = "hashicorp/google" + source = "hashicorp/google" + version = "~> 5.1" } } + required_version = ">= 1.3.0" } ########################################## @@ -64,4 +66,4 @@ resource "google_compute_router_nat" "router_nat" { source_ip_ranges_to_nat = ["ALL_IP_RANGES"] } } -} \ No newline at end of file +} diff --git a/modules/network/terraform.tfvars.example b/modules/network/terraform.tfvars.example new file mode 100644 index 00000000..480c24db --- /dev/null +++ b/modules/network/terraform.tfvars.example @@ -0,0 +1,15 @@ + +# GCP Project ID +project_id = "" + +# GCP Region +region = "" + +# List of VPC Subnets +subnets = "" + +# VPC Description +vpc_description = "" + +# VPC Name +vpc_name = "" \ No newline at end of file diff --git a/modules/network/variables.tf b/modules/network/variables.tf index 69dc33a2..d85ac874 100644 --- a/modules/network/variables.tf +++ b/modules/network/variables.tf @@ -38,36 +38,3 @@ variable "subnets" { })) description = "List of VPC Subnets" } - - -variable "subnet_flow_logs" { - description = "Optional map of boolean to control flow logs (default is disabled), keyed by subnet 'region/name'." - type = map(bool) - default = {} -} - -variable "drain_nat_ips" { - type = list(string) - default = null -} - -variable "log_configs" { - description = "Map keyed by subnet 'region/name' of optional configurations for flow logs when enabled." - type = map(map(string)) - default = {} -} - -variable "log_config_defaults" { - description = "Default configuration for flow logs when enabled (If nothing defined in log_configs)." - type = object({ - aggregation_interval = string - flow_sampling = number - metadata = string - }) - default = { - aggregation_interval = "INTERVAL_5_SEC" - flow_sampling = 0.5 - metadata = "INCLUDE_ALL_METADATA" - } -} - diff --git a/modules/portal-backstage/README.md b/modules/portal-backstage/README.md new file mode 100644 index 00000000..a2ceb9ba --- /dev/null +++ b/modules/portal-backstage/README.md @@ -0,0 +1,42 @@ + +### Requirements + +| Name | Version | +|------|---------| +| terraform | >= 1.3.0 | +| google | ~> 5.1 | +| humanitec | ~> 1.0 | + +### Providers + +| Name | Version | +|------|---------| +| humanitec | ~> 1.0 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| backstage\_postgres | github.com/humanitec-architecture/resource-packs-in-cluster | v2024-06-05//humanitec-resource-defs/postgres/basic | +| portal\_backstage | github.com/humanitec-architecture/shared-terraform-modules | v2024-06-12//modules/portal-backstage | + +### Resources + +| Name | Type | +|------|------| +| [humanitec_application.backstage](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/application) | resource | +| [humanitec_resource_definition_criteria.backstage_postgres](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| github\_app\_client\_id | GitHub App Client ID | `string` | n/a | yes | +| github\_app\_client\_secret | GitHub App Client Secret | `string` | n/a | yes | +| github\_app\_id | GitHub App ID | `string` | n/a | yes | +| github\_app\_private\_key | GitHub App Private Key | `string` | n/a | yes | +| github\_org\_id | GitHub org id | `string` | n/a | yes | +| github\_webhook\_secret | GitHub Webhook Secret | `string` | n/a | yes | +| humanitec\_ci\_service\_user\_token | Humanitec CI Service User Token | `string` | n/a | yes | +| humanitec\_org\_id | Humanitec Organization ID | `string` | n/a | yes | + \ No newline at end of file diff --git a/modules/portal-backstage/main.tf b/modules/portal-backstage/main.tf new file mode 100644 index 00000000..fe374441 --- /dev/null +++ b/modules/portal-backstage/main.tf @@ -0,0 +1,58 @@ +resource "humanitec_application" "backstage" { + id = "backstage" + name = "backstage" +} + +locals { + secrets = { + humanitec-token = var.humanitec_ci_service_user_token + github-app-client-id = var.github_app_client_id + github-app-client-secret = var.github_app_client_secret + github-app-private-key = indent(2, var.github_app_private_key) + github-webhook-secret = var.github_webhook_secret + } + + secret_refs = { + for key, value in local.secrets : key => { + value = value + } + } +} + +module "portal_backstage" { + source = "github.com/humanitec-architecture/shared-terraform-modules?ref=v2024-06-12//modules/portal-backstage" + + cloud_provider = "gcp" + + humanitec_org_id = var.humanitec_org_id + humanitec_app_id = humanitec_application.backstage.id + humanitec_ci_service_user_token_ref = local.secret_refs["humanitec-token"] + + github_org_id = var.github_org_id + github_app_client_id_ref = local.secret_refs["github-app-client-id"] + github_app_client_secret_ref = local.secret_refs["github-app-client-secret"] + github_app_id = var.github_app_id + github_app_private_key_ref = local.secret_refs["github-app-private-key"] + github_webhook_secret_ref = local.secret_refs["github-webhook-secret"] +} + +# Configure required resources for backstage + +locals { + res_def_prefix = "backstage-" +} + +# in-cluster postgres + +module "backstage_postgres" { + source = "github.com/humanitec-architecture/resource-packs-in-cluster?ref=v2024-06-05//humanitec-resource-defs/postgres/basic" + + prefix = local.res_def_prefix +} + +resource "humanitec_resource_definition_criteria" "backstage_postgres" { + resource_definition_id = module.backstage_postgres.id + app_id = humanitec_application.backstage.id + + force_delete = true +} diff --git a/modules/portal-backstage/providers.tf b/modules/portal-backstage/providers.tf new file mode 100644 index 00000000..f7d0d988 --- /dev/null +++ b/modules/portal-backstage/providers.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + google = { + source = "hashicorp/google" + version = "~> 5.1" + } + humanitec = { + source = "humanitec/humanitec" + version = "~> 1.0" + } + } + required_version = ">= 1.3.0" +} diff --git a/modules/portal-backstage/terraform.tfvars.example b/modules/portal-backstage/terraform.tfvars.example new file mode 100644 index 00000000..8b207b4e --- /dev/null +++ b/modules/portal-backstage/terraform.tfvars.example @@ -0,0 +1,24 @@ + +# GitHub App Client ID +github_app_client_id = "" + +# GitHub App Client Secret +github_app_client_secret = "" + +# GitHub App ID +github_app_id = "" + +# GitHub App Private Key +github_app_private_key = "" + +# GitHub org id +github_org_id = "" + +# GitHub Webhook Secret +github_webhook_secret = "" + +# Humanitec CI Service User Token +humanitec_ci_service_user_token = "" + +# Humanitec Organization ID +humanitec_org_id = "" \ No newline at end of file diff --git a/modules/portal-backstage/variables.tf b/modules/portal-backstage/variables.tf new file mode 100644 index 00000000..4437cf6e --- /dev/null +++ b/modules/portal-backstage/variables.tf @@ -0,0 +1,40 @@ +variable "humanitec_org_id" { + description = "Humanitec Organization ID" + type = string +} + +variable "humanitec_ci_service_user_token" { + description = "Humanitec CI Service User Token" + type = string + sensitive = true +} + +variable "github_org_id" { + description = "GitHub org id" + type = string +} + +variable "github_app_client_id" { + description = "GitHub App Client ID" + type = string +} + +variable "github_app_client_secret" { + description = "GitHub App Client Secret" + type = string +} + +variable "github_app_id" { + description = "GitHub App ID" + type = string +} + +variable "github_webhook_secret" { + description = "GitHub Webhook Secret" + type = string +} + +variable "github_app_private_key" { + description = "GitHub App Private Key" + type = string +} diff --git a/providers.tf b/providers.tf new file mode 100644 index 00000000..dc5063e9 --- /dev/null +++ b/providers.tf @@ -0,0 +1,63 @@ +terraform { + required_providers { + github = { + source = "integrations/github" + version = "~> 5.38" + } + google = { + source = "hashicorp/google" + version = "~> 5.1" + } + helm = { + source = "hashicorp/helm" + version = "~> 2.12" + } + humanitec = { + source = "humanitec/humanitec" + version = "~> 1.0" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 2.25" + } + random = { + source = "hashicorp/random" + version = "~> 3.5" + } + } + required_version = ">= 1.3.0" +} + +provider "humanitec" { + org_id = var.humanitec_org_id +} + +provider "github" { + owner = var.github_org_id +} + +provider "google" { + project = var.project_id +} + +provider "kubernetes" { + host = module.base.gke_endpoint + cluster_ca_certificate = module.base.gke_ca_certificate + + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "gke-gcloud-auth-plugin" + } +} + +provider "helm" { + kubernetes { + host = module.base.gke_endpoint + cluster_ca_certificate = module.base.gke_ca_certificate + + exec { + api_version = "client.authentication.k8s.io/v1beta1" + command = "gke-gcloud-auth-plugin" + } + } +} diff --git a/terraform.tfvars.example b/terraform.tfvars.example index 384ac348..6faf1128 100644 --- a/terraform.tfvars.example +++ b/terraform.tfvars.example @@ -5,7 +5,16 @@ environment = "" # The environment type to associate the reference architecture with. environment_type = "development" -# ID of the Humanitec Organization to associate resources with. +# Google Artifact Registry repository ID. +gar_repository_id = "htc-ref-arch" + +# Location of the Google Artifact Registry repository, +gar_repository_location = "" + +# GitHub org id (required for Backstage) +github_org_id = "" + +# Humanitec Organization ID (required for Backstage) humanitec_org_id = "" # A prefix that will be attached to all IDs created in Humanitec. @@ -15,4 +24,7 @@ humanitec_prefix = "htc-ref-arch-" project_id = "" # GCP Region to provision resources in. -region = "" \ No newline at end of file +region = "" + +# Deploy Backstage +with_backstage = false \ No newline at end of file diff --git a/variables.tf b/variables.tf index edf2910d..5cb5359a 100644 --- a/variables.tf +++ b/variables.tf @@ -13,10 +13,15 @@ variable "region" { description = "GCP Region to provision resources in." } +variable "gar_repository_location" { + type = string + description = "Location of the Google Artifact Registry repository," +} -variable "humanitec_org_id" { +variable "gar_repository_id" { type = string - description = "ID of the Humanitec Organization to associate resources with." + description = "Google Artifact Registry repository ID." + default = "htc-ref-arch" } ########################################## @@ -39,4 +44,22 @@ variable "humanitec_prefix" { type = string description = "A prefix that will be attached to all IDs created in Humanitec." default = "htc-ref-arch-" -} \ No newline at end of file +} + +variable "with_backstage" { + description = "Deploy Backstage" + type = bool + default = false +} + +variable "github_org_id" { + description = "GitHub org id (required for Backstage)" + type = string + default = null +} + +variable "humanitec_org_id" { + description = "Humanitec Organization ID (required for Backstage)" + type = string + default = null +} From 4432aed12738d706aa3aa8f26549f06715926868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20W=C3=BCrbach?= Date: Thu, 13 Jun 2024 10:04:18 +0200 Subject: [PATCH 2/2] chore: update readme Co-authored-by: Nils Balkow-Tychsen --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d278ffc0..4b7ade21 100644 --- a/README.md +++ b/README.md @@ -189,7 +189,7 @@ Backstage requires a GitHub connection, which in turn needs: #### Portal Usage -* Enable `with_backstage` inside your `terraform.tfvars` and configure the additional variables that a required for Backstage. +* Enable `with_backstage` inside your `terraform.tfvars` and configure the additional variables that are required for Backstage. * Perform another `terraform apply` #### Verify portal setup