From 731c5a34db0d097f0d231d92b38ac8b963f6cf0f Mon Sep 17 00:00:00 2001 From: Jakub Adamus Date: Thu, 15 Jun 2023 18:11:24 +0200 Subject: [PATCH] Refactor RabbitMQ app registration to be reusable (generic App Registraion) Signed-off-by: Jakub Adamus --- terraform/main.tf | 17 ++-- .../modules/azure/app-registration/main.tf | 78 +++++++++++++++++ .../modules/azure/app-registration/outputs.tf | 11 +++ .../modules/azure/app-registration/vars.tf | 19 ++++ .../azure/rabbitmq-app-registration/main.tf | 86 ------------------- .../rabbitmq-app-registration/outputs.tf | 7 -- .../azure/rabbitmq-app-registration/vars.tf | 10 --- 7 files changed, 119 insertions(+), 109 deletions(-) create mode 100644 terraform/modules/azure/app-registration/main.tf create mode 100644 terraform/modules/azure/app-registration/outputs.tf create mode 100644 terraform/modules/azure/app-registration/vars.tf delete mode 100644 terraform/modules/azure/rabbitmq-app-registration/main.tf delete mode 100644 terraform/modules/azure/rabbitmq-app-registration/outputs.tf delete mode 100644 terraform/modules/azure/rabbitmq-app-registration/vars.tf diff --git a/terraform/main.tf b/terraform/main.tf index 43a6673..4091ca1 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -203,10 +203,19 @@ module "azure_storage_account" { } module "azure_rabbitmq_app_registration" { - source = "./modules/azure/rabbitmq-app-registration" + source = "./modules/azure/app-registration" unique_project_name = var.unique_project_name + application_purpose = "rabbitmq-oauth" + # list of roles to create in application - see https://www.rabbitmq.com/oauth2.html#scope-and-tags + app_roles = { + management = "rabbitmq.tag:management" + administrator = "rabbitmq.tag:administrator" + read_all = "rabbitmq.read:*/*/*" + write_all = "rabbitmq.write:*/*/*" + configure_all = "rabbitmq.configure:*/*/*" + } - rabbitmq_access_identities = [ + access_identities = [ module.azuread_applications.identity_1, module.azuread_applications.identity_2 ] @@ -326,9 +335,5 @@ module "github_secrets" { name = "TF_AZURE_RABBIT_API_APPLICATION_ID" value = module.azure_rabbitmq_app_registration.application_id }, - { - name = "TF_AZURE_RABBIT_API_APPLICATION_SCOPE_NAME" - value = module.azure_rabbitmq_app_registration.application_scope_name - }, ] } diff --git a/terraform/modules/azure/app-registration/main.tf b/terraform/modules/azure/app-registration/main.tf new file mode 100644 index 0000000..10987e2 --- /dev/null +++ b/terraform/modules/azure/app-registration/main.tf @@ -0,0 +1,78 @@ +terraform { + required_providers { + azuread = { + source = "hashicorp/azuread" + } + } +} + +locals { + application_name = "${var.unique_project_name}-${var.application_purpose}" + application_identifier = "api://${local.application_name}" +} + +resource "random_uuid" "app_roles" { + for_each = var.app_roles +} + +resource "random_uuid" "app_scope" {} + +resource "azuread_application" "oauth2_api" { + + display_name = "${local.application_name} OAuth2 API tokens app ${var.application_purpose}" + + api { + mapped_claims_enabled = true + requested_access_token_version = 2 + + oauth2_permission_scope { + id = random_uuid.app_scope.id + admin_consent_description = "Dummy text for dummy application" + admin_consent_display_name = "Dummy text for dummy application" + enabled = true + type = "User" + user_consent_description = "Dummy text for dummy application" + user_consent_display_name = "Dummy text for dummy application" + value = "access" + } + } + + identifier_uris = [local.application_identifier] + + dynamic "app_role" { + for_each = var.app_roles + content { + id = random_uuid.app_roles[app_role.key].id + allowed_member_types = ["User", "Application"] + value = app_role.value + display_name = app_role.key + description = app_role.key + enabled = true + } + } +} + +resource "azuread_service_principal" "oauth2_api" { + application_id = azuread_application.oauth2_api.application_id + use_existing = true +} + +locals { + # assign each role to each identity requested + roles_to_principals = flatten([ + for role,_ in var.app_roles : [ + for identity in var.access_identities : { + role_uuid_key = random_uuid.app_roles[role].id + principal_id = identity.principal_id + } + ] + ]) +} + +resource "azuread_app_role_assignment" "oauth2_api_access" { + count = length(local.roles_to_principals) + + app_role_id = local.roles_to_principals[count.index].role_uuid_key + principal_object_id = local.roles_to_principals[count.index].principal_id + resource_object_id = azuread_service_principal.oauth2_api.object_id +} diff --git a/terraform/modules/azure/app-registration/outputs.tf b/terraform/modules/azure/app-registration/outputs.tf new file mode 100644 index 0000000..96dc7f6 --- /dev/null +++ b/terraform/modules/azure/app-registration/outputs.tf @@ -0,0 +1,11 @@ +output "application_id" { + value = azuread_application.oauth2_api.application_id +} + +output "application_scope_id" { + value = random_uuid.app_scope.id +} + +output "application_identifier_uri" { + value = local.application_identifier +} diff --git a/terraform/modules/azure/app-registration/vars.tf b/terraform/modules/azure/app-registration/vars.tf new file mode 100644 index 0000000..0424a8a --- /dev/null +++ b/terraform/modules/azure/app-registration/vars.tf @@ -0,0 +1,19 @@ +variable "unique_project_name" { + type = string + description = "Value to make unique every resource name generated" +} + +variable "application_purpose" { + type = string + description = "Value to create app name / app identifier from" +} + +variable "app_roles" { + type = map(string) + description = "Role names of application" +} + +variable "access_identities" { + type = list(any) + description = "Identities with access to this application (all roles)" +} diff --git a/terraform/modules/azure/rabbitmq-app-registration/main.tf b/terraform/modules/azure/rabbitmq-app-registration/main.tf deleted file mode 100644 index 5da01ac..0000000 --- a/terraform/modules/azure/rabbitmq-app-registration/main.tf +++ /dev/null @@ -1,86 +0,0 @@ -terraform { - required_providers { - azured = { - source = "hashicorp/azurerm" - } - } -} - -locals { - application_name = "${var.unique_project_name}-rabbitmq-app" - # list of roles to create in application - see https://www.rabbitmq.com/oauth2.html#scope-and-tags - rabbitmq_roles = { - management = "tag:management" - administrator = "tag:administrator" - read_all = "read:*/*/*" - write_all = "write:*/*/*" - configure_all = "configure:*/*/*" - } - rabbitmq_app_identifier = "api://${local.application_name}" -} - -resource "random_uuid" "rabbit_app_role" { - for_each = local.rabbitmq_roles -} - -resource "random_uuid" "rabbit_app_scope" {} - -resource "azuread_application" "rabbit_oauth2_api" { - - display_name = "${local.application_name} OAuth2 API tokens app for RabbitMQ" - - api { - mapped_claims_enabled = true - requested_access_token_version = 2 - - oauth2_permission_scope { - id = random_uuid.rabbit_app_scope.id - admin_consent_description = "Dummy text for dummy application" - admin_consent_display_name = "Dummy text for dummy application" - enabled = true - type = "User" - user_consent_description = "Dummy text for dummy application" - user_consent_display_name = "Dummy text for dummy application" - value = "access" - } - } - - identifier_uris = [local.rabbitmq_app_identifier] - - dynamic "app_role" { - for_each = local.rabbitmq_roles - content { - id = random_uuid.rabbit_app_role[app_role.key].id - allowed_member_types = ["User", "Application"] - value = "${local.rabbitmq_app_identifier}.${app_role.value}" # prefixed for RabbitMQ - display_name = app_role.key - description = "${app_role.key} role for RabbitMQ instance" - enabled = true - } - } -} - -resource "azuread_service_principal" "rabbit_oauth2_api" { - application_id = azuread_application.rabbit_oauth2_api.application_id - use_existing = true -} - -locals { - # assign each role to each identity requested - rabbit_oauth2_api_roles = flatten([ - for role,_ in local.rabbitmq_roles : [ - for identity in var.rabbitmq_access_identities : { - role_uuid_key = random_uuid.rabbit_app_role[role].id - principal_id = identity.principal_id - } - ] - ]) -} - -resource "azuread_app_role_assignment" "rabbit_oauth2_api_access" { - count = length(local.rabbit_oauth2_api_roles) - - app_role_id = local.rabbit_oauth2_api_roles[count.index].role_uuid_key - principal_object_id = local.rabbit_oauth2_api_roles[count.index].principal_id - resource_object_id = azuread_service_principal.rabbit_oauth2_api.object_id -} diff --git a/terraform/modules/azure/rabbitmq-app-registration/outputs.tf b/terraform/modules/azure/rabbitmq-app-registration/outputs.tf deleted file mode 100644 index 8daf399..0000000 --- a/terraform/modules/azure/rabbitmq-app-registration/outputs.tf +++ /dev/null @@ -1,7 +0,0 @@ -output "application_id" { - value = azuread_application.rabbit_oauth2_api.application_id -} - -output "application_scope_name" { - value = local.rabbitmq_app_identifier -} diff --git a/terraform/modules/azure/rabbitmq-app-registration/vars.tf b/terraform/modules/azure/rabbitmq-app-registration/vars.tf deleted file mode 100644 index 6c4d749..0000000 --- a/terraform/modules/azure/rabbitmq-app-registration/vars.tf +++ /dev/null @@ -1,10 +0,0 @@ -variable "unique_project_name" { - type = string - description = "Value to make unique every resource name generated" -} - -variable "rabbitmq_access_identities" { - type = list(any) - description = "Identities with access to RabbitMQ API" - default = [{"principal_id": "20b1b5f8-67b6-460c-8074-b7f836fc06df"}] -} \ No newline at end of file