-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from johanneswuerbach/backstage
feat: backstage example
- Loading branch information
Showing
15 changed files
with
721 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
# Azure reference architecture with Backstage | ||
|
||
Provisions the Azure 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 EKS cluster via `kubectl`. See the [Azure documentation](https://learn.microsoft.com/en-us/azure/aks/learn/quick-kubernetes-deploy-cli#connect-to-the-cluster) or use this command: | ||
|
||
``` | ||
az aks get-credentials --resource-group ref-arch --name ref-arch-aks | ||
``` | ||
|
||
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 | ||
|
||
<!-- BEGIN_TF_DOCS --> | ||
### Requirements | ||
|
||
| Name | Version | | ||
|------|---------| | ||
| terraform | >= 1.3.0 | | ||
| Azure | ~> 5.17 | | ||
| github | ~> 5.38 | | ||
| humanitec | ~> 0.13 | | ||
|
||
### Providers | ||
|
||
| Name | Version | | ||
|------|---------| | ||
| Azure | ~> 5.17 | | ||
| github | ~> 5.38 | | ||
| humanitec | ~> 0.13 | | ||
|
||
### Modules | ||
|
||
| Name | Source | Version | | ||
|------|--------|---------| | ||
| backstage\_ecr | terraform-Azure-modules/ecr/Azure | ~> 1.6 | | ||
| backstage\_iam\_policy\_ecr\_create\_repository | git::<https://github.com/humanitec-architecture/resource-packs-Azure.git//humanitec-resource-defs/iam-policy/ecr-create-repository> | n/a | | ||
| backstage\_iam\_role\_service\_account | git::<https://github.com/humanitec-architecture/resource-packs-Azure.git//humanitec-resource-defs/iam-role/service-account> | n/a | | ||
| backstage\_k8s\_service\_account | git::<https://github.com/humanitec-architecture/resource-packs-Azure.git//humanitec-resource-defs/k8s/service-account> | n/a | | ||
| 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 | | ||
| backstage\_workload | git::<https://github.com/humanitec-architecture/resource-packs-Azure.git//humanitec-resource-defs/workload/service-account> | n/a | | ||
| base | ../../modules/base | n/a | | ||
| iam\_github\_oidc\_provider | terraform-Azure-modules/iam/Azure//modules/iam-github-oidc-provider | ~> 5.30 | | ||
| iam\_github\_oidc\_role | terraform-Azure-modules/iam/Azure//modules/iam-github-oidc-role | ~> 5.30 | | ||
|
||
### Resources | ||
|
||
| Name | Type | | ||
|------|------| | ||
| [Azure_iam_policy.ecr_push_policy](https://registry.terraform.io/providers/hashicorp/Azure/latest/docs/resources/iam_policy) | resource | | ||
| [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_Azure_region](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | resource | | ||
| [github_actions_organization_variable.backstage_Azure_role_arn](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/actions_organization_variable) | 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_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 | | ||
| [humanitec_application.backstage](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/application) | resource | | ||
| [humanitec_resource_definition_criteria.backstage_iam_policy_ecr_create_repository](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | | ||
| [humanitec_resource_definition_criteria.backstage_iam_role_service_account](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | | ||
| [humanitec_resource_definition_criteria.backstage_k8s_service_account](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | 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_resource_definition_criteria.backstage_workload](https://registry.terraform.io/providers/humanitec/humanitec/latest/docs/resources/resource_definition_criteria) | resource | | ||
| [humanitec_value.Azure_default_region](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 | | ||
|
||
### Inputs | ||
|
||
| Name | Description | Type | Default | Required | | ||
|------|-------------|------|---------|:--------:| | ||
| Azure\_account\_id | Azure Account (ID) to use | `string` | n/a | yes | | ||
| Azure\_region | Azure region | `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 | | ||
| disk\_size | Disk size in GB to use for EKS nodes | `number` | `20` | no | | ||
| instance\_types | List of EC2 instances types to use for EKS nodes | `list(string)` | <pre>[<br> "t3.large"<br>]</pre> | no | | ||
| resource\_packs\_Azure\_rev | Revision of the resource-packs-Azure repository to use | `string` | `"refs/heads/main"` | no | | ||
<!-- END_TF_DOCS --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
locals { | ||
name = "gha-acr-push" | ||
cloud_provider = "azure" | ||
github_issuer_url = "https://token.actions.githubusercontent.com" | ||
} | ||
|
||
# User for GHA allowed to push images using OpenID Connect (OIDC) so we don't need to store credentials in GitHub | ||
# Reference https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-azure | ||
|
||
resource "azurerm_user_assigned_identity" "github_oidc_identity" { | ||
name = local.name | ||
location = module.base.az_resource_group_location | ||
resource_group_name = module.base.az_resource_group_name | ||
} | ||
|
||
resource "azurerm_federated_identity_credential" "github_oidc_identity" { | ||
name = "github-action-identity" | ||
resource_group_name = module.base.az_resource_group_name | ||
audience = ["api://AzureADTokenExchange"] | ||
issuer = local.github_issuer_url | ||
subject = "repository_owner:${var.github_org_id}" # configured in github_actions_organization_oidc_subject_claim_customization_template | ||
parent_id = azurerm_user_assigned_identity.github_oidc_identity.id | ||
} | ||
|
||
resource "azurerm_role_assignment" "github_oidc_identity_acr" { | ||
scope = module.base.az_container_registry_id | ||
role_definition_name = "AcrPush" | ||
principal_id = azurerm_user_assigned_identity.github_oidc_identity.principal_id | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# 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"] | ||
} | ||
|
||
locals { | ||
backstage_repo = "backstage" | ||
} | ||
|
||
resource "github_actions_organization_variable" "backstage_cloud_provider" { | ||
variable_name = "CLOUD_PROVIDER" | ||
visibility = "all" | ||
value = local.cloud_provider | ||
} | ||
|
||
resource "github_actions_organization_variable" "backstage_azure_client_id" { | ||
variable_name = "AZURE_CLIENT_ID" | ||
visibility = "all" | ||
value = azurerm_user_assigned_identity.github_oidc_identity.client_id | ||
} | ||
|
||
resource "github_actions_organization_variable" "backstage_azure_tenant_id" { | ||
variable_name = "AZURE_TENANT_ID" | ||
visibility = "all" | ||
value = azurerm_user_assigned_identity.github_oidc_identity.tenant_id | ||
} | ||
|
||
resource "github_actions_organization_variable" "backstage_azure_subscription_id" { | ||
variable_name = "AZURE_SUBSCRIPTION_ID" | ||
visibility = "all" | ||
value = var.subscription_id | ||
} | ||
|
||
resource "github_actions_organization_variable" "backstage_azure_acr_name" { | ||
variable_name = "AZURE_ACR_NAME" | ||
visibility = "all" | ||
value = module.base.az_container_registry_name | ||
} | ||
|
||
resource "github_actions_organization_variable" "backstage_humanitec_org_id" { | ||
variable_name = "HUMANITEC_ORG_ID" | ||
visibility = "all" | ||
value = var.humanitec_org_id | ||
} | ||
|
||
resource "github_actions_organization_secret" "backstage_humanitec_token" { | ||
secret_name = "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, | ||
humanitec_application.backstage, | ||
humanitec_resource_definition_criteria.backstage_postgres, | ||
github_actions_organization_secret.backstage_humanitec_token, | ||
] | ||
} | ||
|
||
# Required as Azure doesn't support wildcards in scopes https://github.com/Azure/azure-workload-identity/issues/373 | ||
# More details in https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect#customizing-the-token-claims | ||
resource "github_actions_repository_oidc_subject_claim_customization_template" "backstage" { | ||
repository = github_repository.backstage.name | ||
use_default = false | ||
include_claim_keys = ["repository_owner"] | ||
} |
Oops, something went wrong.