diff --git a/infrastructure/transform/auth.tf b/infrastructure/transform/auth.tf new file mode 100644 index 00000000..2eb7ea18 --- /dev/null +++ b/infrastructure/transform/auth.tf @@ -0,0 +1,94 @@ +# Copyright (c) University College London Hospitals NHS Foundation Trust +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# AAD App + secret to set as AAD Admin of SQL Server +resource "azuread_application" "flowehr_sql_owner" { + display_name = local.sql_owner_app_name + owners = [data.azurerm_client_config.current.object_id] +} +resource "azuread_application_password" "flowehr_sql_owner" { + application_object_id = azuread_application.flowehr_sql_owner.object_id +} +resource "azuread_service_principal" "flowehr_sql_owner" { + application_id = azuread_application.flowehr_sql_owner.application_id + owners = [data.azurerm_client_config.current.object_id] +} + +# AAD App + SPN for Databricks -> SQL Access +resource "azuread_application" "flowehr_databricks_sql" { + display_name = local.databricks_sql_app_name + owners = [data.azurerm_client_config.current.object_id] +} +resource "azuread_application_password" "flowehr_databricks_sql" { + application_object_id = azuread_application.flowehr_databricks_sql.object_id +} +resource "azuread_service_principal" "flowehr_databricks_sql" { + application_id = azuread_application.flowehr_databricks_sql.application_id + owners = [data.azurerm_client_config.current.object_id] +} + +# AAD App + secret for connecting to external sources +resource "azuread_application" "flowehr_external_connection" { + display_name = local.external_connection_app_name + owners = [data.azurerm_client_config.current.object_id] +} +resource "azuread_application_password" "flowehr_external_connection" { + application_object_id = azuread_application.flowehr_external_connection.object_id +} +resource "azuread_service_principal" "flowehr_external_connection" { + application_id = azuread_application.flowehr_external_connection.application_id + owners = [data.azurerm_client_config.current.object_id] +} + +# Push secrets to KV +resource "azurerm_key_vault_secret" "sql_server_owner_app_id" { + name = "sql-owner-app-id" + value = azuread_application.flowehr_sql_owner.application_id + key_vault_id = var.core_kv_id +} +resource "azurerm_key_vault_secret" "sql_server_owner_secret" { + name = "sql-owner-secret" + value = azuread_application_password.flowehr_sql_owner.value + key_vault_id = var.core_kv_id +} +resource "azurerm_key_vault_secret" "sql_server_features_admin_username" { + name = "sql-features-admin-username" + value = local.sql_server_features_admin_username + key_vault_id = var.core_kv_id +} +resource "azurerm_key_vault_secret" "sql_server_features_admin_password" { + name = "sql-features-admin-password" + value = random_password.sql_admin_password.result + key_vault_id = var.core_kv_id +} +resource "azurerm_key_vault_secret" "flowehr_databricks_sql_spn_app_id" { + name = "flowehr-dbks-sql-app-id" + value = azuread_service_principal.flowehr_databricks_sql.application_id + key_vault_id = var.core_kv_id +} +resource "azurerm_key_vault_secret" "flowehr_databricks_sql_spn_app_secret" { + name = "flowehr-dbks-sql-app-secret" + value = azuread_application_password.flowehr_databricks_sql.value + key_vault_id = var.core_kv_id +} +resource "azurerm_key_vault_secret" "flowehr_external_connection_app_id" { + name = "flowehr-external-conn-app-id" + value = azuread_service_principal.flowehr_external_connection.application_id + key_vault_id = var.core_kv_id +} +resource "azurerm_key_vault_secret" "flowehr_external_connection_app_secret" { + name = "flowehr-external-conn-app-secret" + value = azuread_application_password.flowehr_external_connection.value + key_vault_id = var.core_kv_id +} diff --git a/infrastructure/transform/databricks.tf b/infrastructure/transform/databricks.tf index 44410042..d1b8eee2 100644 --- a/infrastructure/transform/databricks.tf +++ b/infrastructure/transform/databricks.tf @@ -94,6 +94,11 @@ resource "databricks_cluster" "cluster" { "spark.secret.feature-store-fqdn" = "{{secrets/${databricks_secret_scope.secrets.name}/${databricks_secret.flowehr_databricks_sql_fqdn.key}}}" "spark.secret.feature-store-database" = "{{secrets/${databricks_secret_scope.secrets.name}/${databricks_secret.flowehr_databricks_sql_database.key}}}" }), + # Secrets for FlowEHR External app + tomap({ + "spark.secret.external-connection-app-id" = "{{secrets/${databricks_secret_scope.secrets.name}/${databricks_secret.external_connection_spn_app_id.key}}}" + "spark.secret.exernal-connection-app-secret" = "{{secrets/${databricks_secret_scope.secrets.name}/${databricks_secret.external_connection_spn_app_secret.key}}}" + }), # MSI connection to Datalake (if enabled) var.transform.datalake != null ? tomap({ "fs.azure.account.auth.type.${module.datalake[0].adls_name}.dfs.core.windows.net" = "OAuth", diff --git a/infrastructure/transform/feature-data-store.tf b/infrastructure/transform/feature-data-store.tf index f597f1da..58c65432 100644 --- a/infrastructure/transform/feature-data-store.tf +++ b/infrastructure/transform/feature-data-store.tf @@ -20,19 +20,6 @@ resource "random_password" "sql_admin_password" { min_special = 2 } -# AAD App + secret to set as AAD Admin of SQL Server -resource "azuread_application" "flowehr_sql_owner" { - display_name = local.sql_owner_app_name - owners = [data.azurerm_client_config.current.object_id] -} -resource "azuread_application_password" "flowehr_sql_owner" { - application_object_id = azuread_application.flowehr_sql_owner.object_id -} -resource "azuread_service_principal" "flowehr_sql_owner" { - application_id = azuread_application.flowehr_sql_owner.application_id - owners = [data.azurerm_client_config.current.object_id] -} - # Azure SQL logical server, public access disabled - will use private endpoints for access resource "azurerm_mssql_server" "sql_server_features" { name = "sql-server-features-${lower(var.naming_suffix)}" @@ -145,51 +132,6 @@ resource "null_resource" "create_sql_user" { } } -# AAD App + SPN for Databricks -> SQL Access -resource "azuread_application" "flowehr_databricks_sql" { - display_name = local.databricks_sql_app_name - owners = [data.azurerm_client_config.current.object_id] -} -resource "azuread_application_password" "flowehr_databricks_sql" { - application_object_id = azuread_application.flowehr_databricks_sql.object_id -} -resource "azuread_service_principal" "flowehr_databricks_sql" { - application_id = azuread_application.flowehr_databricks_sql.application_id - owners = [data.azurerm_client_config.current.object_id] -} - -# Push secrets to KV -resource "azurerm_key_vault_secret" "sql_server_owner_app_id" { - name = "sql-owner-app-id" - value = azuread_application.flowehr_sql_owner.application_id - key_vault_id = var.core_kv_id -} -resource "azurerm_key_vault_secret" "sql_server_owner_secret" { - name = "sql-owner-secret" - value = azuread_application_password.flowehr_sql_owner.value - key_vault_id = var.core_kv_id -} -resource "azurerm_key_vault_secret" "sql_server_features_admin_username" { - name = "sql-features-admin-username" - value = local.sql_server_features_admin_username - key_vault_id = var.core_kv_id -} -resource "azurerm_key_vault_secret" "sql_server_features_admin_password" { - name = "sql-features-admin-password" - value = random_password.sql_admin_password.result - key_vault_id = var.core_kv_id -} -resource "azurerm_key_vault_secret" "flowehr_databricks_sql_spn_app_id" { - name = "flowehr-dbks-sql-app-id" - value = azuread_service_principal.flowehr_databricks_sql.application_id - key_vault_id = var.core_kv_id -} -resource "azurerm_key_vault_secret" "flowehr_databricks_sql_spn_app_secret" { - name = "flowehr-dbks-sql-app-secret" - value = azuread_application_password.flowehr_databricks_sql.value - key_vault_id = var.core_kv_id -} - resource "azurerm_private_endpoint" "sql_server_features_pe" { name = "pe-sql-feature-data-${var.naming_suffix}" resource_group_name = var.core_rg_name diff --git a/infrastructure/transform/locals.tf b/infrastructure/transform/locals.tf index 5fc916b5..88ed6815 100644 --- a/infrastructure/transform/locals.tf +++ b/infrastructure/transform/locals.tf @@ -17,6 +17,7 @@ locals { sql_owner_app_name = "flowehr-sql-owner-${lower(var.naming_suffix)}" databricks_adls_app_name = "flowehr-databricks-adls-${lower(var.naming_suffix)}" databricks_sql_app_name = "flowehr-databricks-datawriter-${lower(var.naming_suffix)}" + external_connection_app_name = "flowehr-external-${lower(var.naming_suffix)}" pipeline_file = "pipeline.json" trigger_file = "trigger.json" artifacts_dir = "artifacts" diff --git a/infrastructure/transform/secrets.tf b/infrastructure/transform/secrets.tf index 89e11a0a..cc2a53a8 100644 --- a/infrastructure/transform/secrets.tf +++ b/infrastructure/transform/secrets.tf @@ -70,6 +70,18 @@ resource "databricks_secret" "flowehr_databricks_sql_database" { string_value = azurerm_mssql_database.feature_database.name scope = databricks_secret_scope.secrets.id } +# FlowEHR external app secrets +resource "databricks_secret" "external_connection_spn_app_id" { + key = "flowehr-external-connection-app-id" + string_value = azuread_service_principal.flowehr_external_connection.application_id + scope = databricks_secret_scope.secrets.id +} + +resource "databricks_secret" "external_connection_spn_app_secret" { + key = "flowehr-external-connection-app-secret" + string_value = azuread_application_password.flowehr_external_connection.value + scope = databricks_secret_scope.secrets.id +} # Additional Databricks secrets passed in from the config resource "databricks_secret" "databricks_config_secret" {