diff --git a/modules/aks/github-connector/backplane/main.tf b/modules/aks/github-connector/backplane/main.tf index 7d144452..f0f7b9e2 100644 --- a/modules/aks/github-connector/backplane/main.tf +++ b/modules/aks/github-connector/backplane/main.tf @@ -9,59 +9,36 @@ # - update image pull secret # - deployment # -data "azurerm_subscription" "current" { +locals { + acr_resource_group_name = coalesce(var.acr.resource_group_name, azurerm_resource_group.bb_github_connector.name) } data "azurerm_kubernetes_cluster" "aks" { - name = "aks" - resource_group_name = "aks-rg" + name = var.aks.cluster_name + resource_group_name = var.aks.resource_group_name } resource "azurerm_resource_group" "bb_github_connector" { - name = "bb-github-connector" - location = "Germany West Central" -} - -# SPN for Terraform state - -resource "azuread_application" "bb_github_connector" { - display_name = "bb-github-connector" -} - -resource "azuread_service_principal" "bb_github_connector" { - client_id = azuread_application.bb_github_connector.client_id -} - -resource "azuread_service_principal_password" "bb_github_connector" { - service_principal_id = azuread_service_principal.bb_github_connector.id -} - -resource "azurerm_role_assignment" "bb_github_connector" { - scope = data.azurerm_subscription.current.id - role_definition_name = "Contributor" # TODO: restrict permissions - principal_id = azuread_service_principal.bb_github_connector.object_id -} - -resource "azurerm_role_assignment" "terraform_state" { - role_definition_name = "Storage Blob Data Owner" - principal_id = azuread_service_principal.bb_github_connector.object_id - scope = var.tfstates_resource_manager_id + name = var.resource_prefix + location = var.acr.location } # Container registry -# We're using a shared container registry for all consumers of this building block. -# This could easily be changed to deploy a dedicated container registry per building block -# or by making the container registry configurable. +# A shared ACR is used for all building block consumers by default. +# Set var.acr.resource_group_name to place the ACR in an existing resource group. resource "azurerm_container_registry" "acr" { - name = "githubconnector" - resource_group_name = azurerm_resource_group.bb_github_connector.name - location = azurerm_resource_group.bb_github_connector.location + name = replace(var.resource_prefix, "-", "") + resource_group_name = local.acr_resource_group_name + location = var.acr.location sku = "Basic" } +# Service principal used by GitHub Actions to push images to ACR. +# Granted AcrPush (not Contributor) — scoped to this registry only. + resource "azuread_application" "bb_github_connector_acr" { - display_name = "bb-github-connector-acr" + display_name = "${var.resource_prefix}-acr" } resource "azuread_service_principal" "bb_github_connector_acr" { @@ -74,7 +51,7 @@ resource "azuread_service_principal_password" "bb_github_connector_acr" { resource "azurerm_role_assignment" "bb_github_connector_acr" { scope = azurerm_container_registry.acr.id - role_definition_name = "Contributor" + role_definition_name = "AcrPush" principal_id = azuread_service_principal.bb_github_connector_acr.object_id } diff --git a/modules/aks/github-connector/backplane/output.tf b/modules/aks/github-connector/backplane/output.tf index 24fb7fd0..a024bef9 100644 --- a/modules/aks/github-connector/backplane/output.tf +++ b/modules/aks/github-connector/backplane/output.tf @@ -2,7 +2,7 @@ output "config_tf" { description = "Generates a config.tf that can be dropped into meshStack's BuildingBlockDefinition as an encrypted file input to configure this building block." sensitive = true value = <<-EOF - provider "kubernetes" { + provider "kubernetes" { host = "${data.azurerm_kubernetes_cluster.aks.kube_admin_config[0].host}" cluster_ca_certificate = base64decode("${data.azurerm_kubernetes_cluster.aks.kube_admin_config[0].cluster_ca_certificate}") client_certificate = base64decode("${data.azurerm_kubernetes_cluster.aks.kube_admin_config[0].client_certificate}") @@ -32,6 +32,5 @@ output "config_tf" { password = "${azuread_service_principal_password.bb_github_connector_acr.value}" } } - EOF +EOF } - diff --git a/modules/aks/github-connector/backplane/variables.tf b/modules/aks/github-connector/backplane/variables.tf index e52da712..4675435a 100644 --- a/modules/aks/github-connector/backplane/variables.tf +++ b/modules/aks/github-connector/backplane/variables.tf @@ -1,20 +1,26 @@ -variable "tfstates_resource_manager_id" { - type = string - nullable = false +variable "resource_prefix" { + type = string + default = "bb-github-connector" + description = "Prefix used for all named resources created by this backplane (resource group, app registrations, ACR)." } -variable "tfstates_resource_group_name" { - type = string - nullable = false +variable "aks" { + type = object({ + cluster_name = string + resource_group_name = string + }) + description = "Reference to the existing AKS cluster this building block connects to." } -variable "tfstates_storage_account_name" { - type = string - nullable = false -} - -variable "tfstates_storage_container_name" { - type = string - nullable = false +variable "acr" { + type = object({ + location = string + resource_group_name = optional(string) + }) + description = "Configuration for the shared Azure Container Registry. resource_group_name defaults to the resource group created by this backplane when omitted." + default = { + location = "Germany West Central" + resource_group_name = null + } } diff --git a/modules/aks/github-connector/meshstack_integration.tf b/modules/aks/github-connector/meshstack_integration.tf new file mode 100644 index 00000000..24de9276 --- /dev/null +++ b/modules/aks/github-connector/meshstack_integration.tf @@ -0,0 +1,238 @@ +terraform { + required_providers { + meshstack = { + source = "meshcloud/meshstack" + version = "~> 0.19.3" + } + } +} + +variable "meshstack" { + type = object({ + owning_workspace_identifier = string + }) +} + +variable "github" { + type = object({ + repo_definition_uuid = string + org = string + app_id = string + app_installation_id = string + app_pem_file = string + }) + description = "GitHub integration configuration. repo_definition_uuid is the UUID of the deployed GitHub repo building block definition. The app_* fields are the GitHub App credentials for the GitHub Terraform provider." +} + +variable "aks" { + type = object({ + connector_config_tf_base64 = string + }) + description = "AKS integration configuration. connector_config_tf_base64 is the base64-encoded config.tf providing a kubeconfig stub (cluster server endpoint and CA certificate) and ACR credentials to the building block run. It does not contain user credentials — those are provisioned by the building block itself." +} + +locals { + config_tf_secret_value = "data:application/octet-stream;base64,${var.aks.connector_config_tf_base64}" +} + +variable "tags" { + type = map(list(string)) + default = {} +} + +variable "notification_subscribers" { + type = list(string) + default = [] +} + +variable "hub" { + type = object({ + git_ref = string + }) + default = { + git_ref = "main" + } + description = "Hub release reference. Set git_ref to a tag (e.g. 'v1.2.3') or branch for the meshstack-hub repo." +} + +resource "meshstack_building_block_definition" "aks_github_connector" { + metadata = { + owned_by_workspace = var.meshstack.owning_workspace_identifier + tags = var.tags + } + + spec = { + description = "CI/CD pipeline using GitHub Actions for secure, scalable AKS deployment. Sets up service accounts, secrets, and workflows for seamless GitHub Actions integration with an AKS namespace." + display_name = "GitHub Actions AKS Connector" + notification_subscribers = var.notification_subscribers + symbol = "https://raw.githubusercontent.com/meshcloud/meshstack-hub/main/modules/aks/github-connector/buildingblock/logo.png" + target_type = "TENANT_LEVEL" + supported_platforms = [{ name = "AZURE_KUBERNETES_SERVICE" }] + + readme = chomp(< [name](#input\_name) | This name will be used for the created projects, app subdomain and GitHub repository. | `string` | n/a | yes | | [project\_tags\_yaml](#input\_project\_tags\_yaml) | YAML configuration for project tags that will be applied to dev and prod projects. Expected structure:
yaml
dev:
key1:
- "value1"
- "value2"
key2:
- "value3"
prod:
key1:
- "value4"
key2:
- "value5"
- "value6"
| `string` | `"dev: {}\nprod: {}\n"` | no | | [repo\_admin](#input\_repo\_admin) | GitHub handle of the user who will be assigned as the repository admin. Delete building block definition input if not needed. | `string` | `null` | no | +| [template\_owner](#input\_template\_owner) | GitHub owner (org or user) of the repository template to use when creating the application repository. | `string` | `"likvid-bank"` | no | +| [template\_repo](#input\_template\_repo) | Name of the GitHub repository template to use when creating the application repository. | `string` | `"aks-starterkit-template"` | no | | [workspace\_identifier](#input\_workspace\_identifier) | n/a | `string` | n/a | yes | ## Outputs diff --git a/modules/aks/starterkit/buildingblock/main.tf b/modules/aks/starterkit/buildingblock/main.tf index c7e2a53d..ca993e8d 100644 --- a/modules/aks/starterkit/buildingblock/main.tf +++ b/modules/aks/starterkit/buildingblock/main.tf @@ -131,10 +131,10 @@ resource "meshstack_building_block_v2" "repo" { value_bool = true } template_owner = { - value_string = "likvid-bank" + value_string = var.template_owner } template_repo = { - value_string = "aks-starterkit-template" + value_string = var.template_repo } } } diff --git a/modules/aks/starterkit/buildingblock/outputs.tf b/modules/aks/starterkit/buildingblock/outputs.tf index e8f45d5d..470f0495 100644 --- a/modules/aks/starterkit/buildingblock/outputs.tf +++ b/modules/aks/starterkit/buildingblock/outputs.tf @@ -1,12 +1,12 @@ output "dev-link" { description = "Link to the dev environment Angular app" - value = "https://${local.identifier}-dev.likvid-k8s.msh.host" + value = "https://${local.identifier}-dev.${var.apps_base_domain}" } output "prod-link" { description = "Link to the prod environment Angular app" - value = "https://${local.identifier}.likvid-k8s.msh.host" + value = "https://${local.identifier}.${var.apps_base_domain}" } output "github_repo_url" { @@ -54,8 +54,8 @@ Trigger a deployment by: View deployment status: [GitHub Actions](${meshstack_building_block_v2.repo.status.outputs.repo_html_url.value_string}/actions/workflows/k8s-deploy.yml) -- **Dev**: [${local.identifier}-dev.likvid-k8s.msh.host](https://${local.identifier}-dev.likvid-k8s.msh.host) -- **Prod**: [${local.identifier}.likvid-k8s.msh.host](https://${local.identifier}.likvid-k8s.msh.host) +- **Dev**: [${local.identifier}-dev.${var.apps_base_domain}](https://${local.identifier}-dev.${var.apps_base_domain}) +- **Prod**: [${local.identifier}.${var.apps_base_domain}](https://${local.identifier}.${var.apps_base_domain}) --- diff --git a/modules/aks/starterkit/buildingblock/variables.tf b/modules/aks/starterkit/buildingblock/variables.tf index 8ba99f5b..9ed8f3f0 100644 --- a/modules/aks/starterkit/buildingblock/variables.tf +++ b/modules/aks/starterkit/buildingblock/variables.tf @@ -112,3 +112,20 @@ EOF error_message = "prod section is required in project_tags_yaml" } } +variable "template_owner" { + type = string + description = "GitHub owner (org or user) of the repository template to use when creating the application repository." + default = "likvid-bank" +} + +variable "template_repo" { + type = string + description = "Name of the GitHub repository template to use when creating the application repository." + default = "aks-starterkit-template" +} + +variable "apps_base_domain" { + type = string + description = "Base domain used for application URLs (e.g. 'likvid-k8s.msh.host'). The app subdomain will be prefixed to this value." + default = "likvid-k8s.msh.host" +} \ No newline at end of file diff --git a/modules/aks/starterkit/meshstack_integration.tf b/modules/aks/starterkit/meshstack_integration.tf index f5d7e2c9..028e83f3 100644 --- a/modules/aks/starterkit/meshstack_integration.tf +++ b/modules/aks/starterkit/meshstack_integration.tf @@ -1,41 +1,119 @@ -locals { - owning_workspace_identifier = "my-workspace" - full_platform_identifier = "aks.k8s" - github_actions_connector_definition_version_uuid = "61f8de01-551d-4f1f-b9c4-ba94323910cd" - github_org = "my-org" - github_repo_definition_uuid = "11240216-2b3c-42db-8e15-c7b595cf207a" - github_repo_definition_version_uuid = "24654b9d-aedd-4dd3-94b0-0bc3bef52cb7" - landing_zone_dev_identifier = "aks-dev" - landing_zone_prod_identifier = "aks-prod" - tags = { +terraform { + required_providers { + meshstack = { + source = "meshcloud/meshstack" + version = "~> 0.19.3" + } } - notification_subscribers = [ - ] - project_tags_yaml = trimspace(<<-YAML -dev: - environment: - - "dev" -prod: - environment: - - "prod" -YAML - ) +} + +variable "meshstack" { + type = object({ + owning_workspace_identifier = string + }) +} + +variable "full_platform_identifier" { + type = string + default = "aks.k8s" +} + +variable "github_actions_connector_definition_version_uuid" { + type = string + default = "00000000-0000-0000-0000-000000000001" +} + +variable "github_org" { + type = string + default = "my-org" +} + +variable "github_repo_definition_uuid" { + type = string + default = "00000000-0000-0000-0000-000000000002" +} + +variable "github_repo_definition_version_uuid" { + type = string + default = "00000000-0000-0000-0000-000000000003" +} + +variable "landing_zone_dev_identifier" { + type = string + default = "aks-dev" +} + +variable "landing_zone_prod_identifier" { + type = string + default = "aks-prod" +} + +variable "tags" { + type = map(list(string)) + default = {} +} + +variable "notification_subscribers" { + type = list(string) + default = [] +} + +variable "hub" { + type = object({ + git_ref = string + }) + default = { + git_ref = "main" + } + description = "Hub release reference. Set git_ref to a tag (e.g. 'v1.2.3') or branch for the meshstack-hub repo." +} + +variable "project_tags_yaml" { + type = string + default = <<-YAML + dev: + environment: + - "dev" + prod: + environment: + - "prod" + YAML +} + +variable "template_owner" { + type = string + description = "GitHub owner (org or user) of the repository template to use when creating the application repository." + default = "likvid-bank" +} + +variable "template_repo" { + type = string + description = "Name of the GitHub repository template to use when creating the application repository." + default = "aks-starterkit-template" +} + +variable "apps_base_domain" { + type = string + description = "Base domain used for application URLs (e.g. 'likvid-k8s.msh.host'). The app subdomain will be prefixed to this value." + default = "likvid-k8s.msh.host" } resource "meshstack_building_block_definition" "aks_starterkit" { metadata = { - owned_by_workspace = local.owning_workspace_identifier - tags = local.tags + owned_by_workspace = var.meshstack.owning_workspace_identifier + tags = var.tags } spec = { - description = "The AKS Starterkit provides application teams with a pre-configured Kubernetes environment following Likvid Bank's best practices. It includes a Git repository, a CI/CD pipeline using GitHub Actions, and a secure container registry integration." + description = "The AKS Starterkit provides application teams with a pre-configured Kubernetes environment following best practices. It includes a Git repository, a CI/CD pipeline using GitHub Actions, and a secure container registry integration." display_name = "AKS Starterkit" - notification_subscribers = local.notification_subscribers + notification_subscribers = var.notification_subscribers + symbol = "https://raw.githubusercontent.com/meshcloud/meshstack-hub/main/modules/aks/starterkit/buildingblock/logo.png" + readme = chomp(<