diff --git a/aks/dfe_analytics/.terraform.lock.hcl b/aks/dfe_analytics/.terraform.lock.hcl new file mode 100644 index 0000000..9aaf8b8 --- /dev/null +++ b/aks/dfe_analytics/.terraform.lock.hcl @@ -0,0 +1,64 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/eppo/environment" { + version = "1.3.5" + constraints = "1.3.5" + hashes = [ + "h1:1Af95/IhzW16rbX8kSApfrAi8vwc5+7uVbCeyVaGw2E=", + "zh:00e7a6bf7f0f09cc4871d7f4fee2c943ce61c05b9802365a97703d6c2e63e3dc", + "zh:018d92e621177d053ed5c32e8220efa8c019852c4d60cc7539683bac28470d9b", + "zh:12ca5162286b80b7f46bd013ae2007641132d201af12bc6adb872f9a0ff85b7a", + "zh:2991085432bd4dc718aadfb37b2cdb6201ef73a8a0e5661411f46d9ec782e678", + "zh:2a8f6801266f89b816ebfdb441411e53f4cf1e0278e853715fb561946ad5a575", + "zh:8783a8dc846d3e71b38ca470066f506dde8040f149402f0d348e5dca7f012909", + "zh:8bc8f61e496e96c81c46e1aa59bf2155b6acc80db1ea462f2ddd665748fcda7f", + "zh:95fb102fecceb3a5b44dbe9fbe262494a0abdb6805addf1286c5d92cd4b0f779", + "zh:a158837ec561c161d3c47068e30bca341e5e4c7abff7fa72b9522438b85af4ac", + "zh:a738a7b2e953ee8059f9e68d48ae954175d001a5480f29e22d717bee9fd93f7f", + "zh:bac4b3a38eed35c91269cd008ad88862f47be99474de85e9a2efcce6564e0c24", + "zh:cd56a12eef3515fa5a5845d550be2f67989c8e65563e8fa9f5060666c0728a7c", + "zh:e3e895bc8b557b36bfa03f251df429aa0fba068f4c7ef0ed6ac551b7cba9ff86", + "zh:e959a9e826e3c33242bf4492ee12e5f8be023cf2461702c43d1833c4a8516232", + "zh:f41d9d60b205e6d536881e4af7bb9fc85ae90858bfddf695f95fbd68e01e0ad3", + ] +} + +provider "registry.terraform.io/hashicorp/azurerm" { + version = "4.5.0" + hashes = [ + "h1:iIQmNl0NPEZsxS8pXTF+VGpxyfXtw5DOB4mW/kvrHy8=", + "zh:27ac12977bdb7b82217a3fe35d3206e1e4261465d738aff93244ec90f2bd431a", + "zh:36a619af3767a92ee892c5de24604eeb9f23a5a01bb8455115a5eb4bd656f234", + "zh:45a374637b794427c5e07d23c6312d92d58bed3594789322c109d333ea1865e5", + "zh:538e501d313cfc0b61f3b2e5be9ae7755df3d3d9a3e4f14e0ea6a943d5102109", + "zh:64d8e4b94a1324292fe318bf27c6149aa345eabab8b89d9d78ce447ce5600e65", + "zh:7b3fcc0a724c5e00e6ce0e7da22010b6ae4bd2622544ef4d31fd4100f85985d7", + "zh:84876a614b010ae5dbef1b1edd9a22447cf57b9300b9eaf4321d587bfebf82dc", + "zh:850e3900fb2b55ad85b6def8b580fb851778bb470be5354cb0a0244d03acd5a4", + "zh:b6355d1eb7d165b246ad9c8f7c0ce7ccd5bbc58a01bd853c7ca896c71f4cd295", + "zh:bd4f1558f24af356d372937b810801555471eafbbc0552471bb6760f8ddd6b7e", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f78eaaf507ab56041112b765f6ca1740221773f3b32710bb8d087f29a686f30f", + ] +} + +provider "registry.terraform.io/hashicorp/google" { + version = "6.6.0" + constraints = "6.6.0" + hashes = [ + "h1:bNj7UyO9+IdcTbkZJgjULH89DrJSaBCRw89zt6g8ajg=", + "zh:0c181f9b9f0ab81731e5c4c2d20b6d342244506687437dad94e279ef2a588f68", + "zh:12a4c333fc0ba670e87f09eb574e4b7da90381f9929ef7c866048b6841cc8a6a", + "zh:15c277c2052df89429051350df4bccabe4cf46068433d4d8c673820d9756fc00", + "zh:35d1663c81b81cd98d768fa7b80874b48c51b27c036a3c598a597f653374d3c8", + "zh:56b268389758d544722a342da4174c486a40ffa2a49b45a06111fe31c6c9c867", + "zh:abd3ea8c3a62928ba09ba7eb42b52f53e682bd65e92d573f1739596b5a9a67b1", + "zh:be55a328d61d9db58690db74ed43614111e1105e5e52cee15acaa062df4e233e", + "zh:ce2317ce9fd02cf14323f9e061c43a415b4ae9b3f96046460d0e6b6529a5aa6c", + "zh:d54a6d8e031c824f1de21b93c3e01ed7fec134b4ae55223d08868c6168c98e47", + "zh:d8c6e33b5467c6eb5a970adb251c4c8194af12db5388cff9d4b250294eae4daa", + "zh:f49e4cc9c0b55b3bec7da64dd698298345634a5df372228ee12aa45e57982f64", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} diff --git a/aks/dfe_analytics/README.md b/aks/dfe_analytics/README.md new file mode 100644 index 0000000..4129914 --- /dev/null +++ b/aks/dfe_analytics/README.md @@ -0,0 +1,123 @@ +# DfE Analytics +Create resources in Google cloud Bigquery and provides the required variables to applications so they can send events. + +## Examples +### Reuse existing dataset and events table + +```hcl +module "dfe_analytics" { + source = "./vendor/modules/dfe-terraform-modules//aks/dfe_analytics" + + azure_resource_prefix = var.azure_resource_prefix + cluster = var.cluster + namespace = var.namespace + service_short = var.service_short + environment = var.environment + gcp_dataset = "events_${var.config}" + gcp_project_id = "apply-for-qts-in-england" + gcp_project_number = 385922361840 +} +``` + +### Create new dataset and events table +Use for a new environment. To get the values for `gcp_taxonomy_id` and `gcp_policy_tag_id` see [Taxonomy and policy tag](#taxonomy-and-policy-tag). +```hcl +module "dfe_analytics" { + source = "./vendor/modules/dfe-terraform-modules//aks/dfe_analytics" + + azure_resource_prefix = var.azure_resource_prefix + cluster = var.cluster + namespace = var.namespace + service_short = var.service_short + environment = var.environment + gcp_keyring = "afqts-key-ring" + gcp_key = "afqts-key" + gcp_project_id = "apply-for-qts-in-england" + gcp_project_number = 385922361840 + gcp_taxonomy_id = 5456044749211275650 + gcp_policy_tag_id = 2399328962407973209 +} +``` + +### Configure application +#### Enable in Ruby +```ruby +DfE::Analytics.configure do |config| +... + config.azure_federated_auth = ENV.include? "GOOGLE_CLOUD_CREDENTIALS" +end +``` + +#### Enable in .NET +```cs +builder.Services.AddDfeAnalytics() + .UseFederatedAksBigQueryClientProvider(); +``` +Ensure the `ProjectNumber`, `WorkloadIdentityPoolName`, `WorkloadIdentityPoolProviderName` and `ServiceAccountEmail` configuration keys are populated within the `DfeAnalytics` configuration section. + +#### Variables +Each variable is available as a separate output. For convenience, the `variables_map` output provides them all: +- BIGQUERY_PROJECT_ID +- BIGQUERY_TABLE_NAME +- BIGQUERY_DATASET +- GOOGLE_CLOUD_CREDENTIALS + +```hcl +module "application_configuration" { + source = "./vendor/modules/dfe-terraform-modules//aks/application_configuration" + ... + secret_variables = merge( + module.dfe_analytics.variables_map, + { + ... + } + ) +} +``` + +#### Enable on each app that requires it +```hcl +module "worker_application" { + source = "./vendor/modules/dfe-terraform-modules//aks/application" + ... + enable_gcp_wif = true +} +``` + +## Authentication - Command line +The user should have Owner role on the Google project. + +- Run `gcloud auth application-default login` +- Run terraform + +## Authentication - Github actions +We set up workfload identity federation on the Google side and configure the workflow. The user should have Owner role on the Google project. This is done once per repository. + +- Run the `authorise_workflow.sh` located in *aks/dfe_analytics*: + ``` + ./authorise_workflow.sh PROJECT_ID REPO + ``` + Example: + ``` + ./authorise_workflow.sh apply-for-qts-in-england apply-for-qualified-teacher-status + ``` +- The script shows the *permissions* and *google-github-actions/auth step* to add to the workflow job +- Adding the permission removes the [default token permissions](https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#permissions-for-the-github_token), which may be an issue for some actions that rely on them. For example, the [marocchino/sticky-pull-request-comment](https://github.com/marocchino/sticky-pull-request-comment) action requires `pull-requests: write`. It must then be added explicitly. +- Run the workflow + +## Taxonomy and policy tag +The user should have Owner role on the Google project. + +- Authenticate: `gcloud auth application-default login` +- Get projects list: `gcloud projects list` +- Select project e.g.: `gcloud config set project apply-for-qts-in-england` +- Get taxonomies list: + ``` + gcloud data-catalog taxonomies list --location=europe-west2 --format="value(name)" + ``` + The path contains the taxonomy id as a number e.g. 5456044749211275650 +- Get policy tags e.g.: + ``` + gcloud data-catalog taxonomies policy-tags list --taxonomy="projects/apply-for-qts-in-england/locations/europe-west2/taxonomies/5456044749211275650" --location="europe-west2" --filter="displayName:hidden" --format="value(name)" + ``` + The path contains the policy tag id as a number e.g. 2399328962407973209 diff --git a/aks/dfe_analytics/authorise_workflow.sh b/aks/dfe_analytics/authorise_workflow.sh new file mode 100644 index 0000000..056240e --- /dev/null +++ b/aks/dfe_analytics/authorise_workflow.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# Set up Direct Workload Identity Federation +# See https://github.com/google-github-actions/auth?tab=readme-ov-file#preferred-direct-workload-identity-federation + +PROJECT_ID=$1 +REPO=$2 + +if [[ -z "$PROJECT_ID" || -z "$REPO" ]]; then + cat <