From 7f59c3e4f0a1fef49e363372e1f7cc40151ff71d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kalle=20Ahlstr=C3=B6m?= Date: Mon, 6 Jan 2025 11:00:41 +0200 Subject: [PATCH] feat: add github-ci module for easy actions OIDC login setup --- main.tf | 21 +++++++++++++-- modules/github-ci/main.tf | 49 ++++++++++++++++++++++++++++++++++ modules/github-ci/outputs.tf | 20 ++++++++++++++ modules/github-ci/variables.tf | 20 ++++++++++++++ 4 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 modules/github-ci/main.tf create mode 100644 modules/github-ci/outputs.tf create mode 100644 modules/github-ci/variables.tf diff --git a/main.tf b/main.tf index b54e610..1ebec82 100644 --- a/main.tf +++ b/main.tf @@ -406,7 +406,24 @@ module "vaultwarden" { module "github-ci-roles" { source = "./modules/github-ci" repo_app_service_map = { - "tietokilta/web" : [module.web.web_app_id, module.web.cms_app_id] - "tietokilta/laskugeneraattori" : [module.invoicing.invoicing_app_id] + "Tietokilta/web" : [module.web.web_app_id, module.web.cms_app_id] + "Tietokilta/laskugeneraattori" : [module.invoicing.invoicing_app_id] } } +# Output Azure Client IDs for Each Repository +output "github_actions_azure_client_ids" { + description = "Mapping of GitHub repositories to their AZURE_CLIENT_ID" + value = module.github-ci-roles.azure_client_ids +} + +# Output Azure Subscription ID +output "github_actions_azure_subscription_id" { + description = "AZURE_SUBSCIPTION_ID in Github Actions" + value = module.github-ci-roles.azure_subscription_id +} + +# Output Azure Tenant ID +output "github_actions_azure_tenant_id" { + description = "AZURE_TENANT_ID in Github Actions" + value = module.github-ci-roles.azure_tenant_id +} diff --git a/modules/github-ci/main.tf b/modules/github-ci/main.tf new file mode 100644 index 0000000..cd61e82 --- /dev/null +++ b/modules/github-ci/main.tf @@ -0,0 +1,49 @@ +data "azurerm_subscription" "primary" { +} + +resource "azuread_application_registration" "github_oidc" { + for_each = var.repo_app_service_map + + display_name = "github-actions-${replace(each.key, "/", "-")}" +} + + +resource "azuread_service_principal" "github_oidc" { + for_each = azuread_application_registration.github_oidc + client_id = each.value.client_id +} + +resource "azuread_application_federated_identity_credential" "github_oidc" { + for_each = azuread_application_registration.github_oidc + application_id = each.value.id + display_name = "github-actions-${replace(each.key, "/", "-")}-federated-credential" + audiences = ["api://AzureADTokenExchange"] + issuer = "https://token.actions.githubusercontent.com" + subject = "repo:${each.key}:ref:refs/heads/main" +} + + +locals { + flattened_role_assignments = flatten([ + for repo, app_services in var.repo_app_service_map : + [ + for app_service in app_services : + { + repo = repo + app_service = app_service + } + ] + ]) +} + +resource "azurerm_role_assignment" "github_oidc_role" { + for_each = { + for assignment in local.flattened_role_assignments : + "${assignment.repo}-${replace(assignment.app_service, "/", "-")}" => assignment + } + + scope = each.value.app_service + # https://github.com/Azure/webapps-deploy?tab=readme-ov-file#configure-deployment-credentials-1 + role_definition_name = "Contributor" + principal_id = azuread_service_principal.github_oidc[each.value.repo].object_id +} diff --git a/modules/github-ci/outputs.tf b/modules/github-ci/outputs.tf new file mode 100644 index 0000000..c70dddd --- /dev/null +++ b/modules/github-ci/outputs.tf @@ -0,0 +1,20 @@ +# Output Azure Client IDs for Each Repository +output "azure_client_ids" { + description = "Mapping of GitHub repositories to their Azure AD Application Client IDs." + value = { + for repo, app in azuread_application_registration.github_oidc : + repo => app.client_id + } +} + +# Output Azure Subscription ID +output "azure_subscription_id" { + description = "Azure Subscription ID." + value = data.azurerm_subscription.primary.subscription_id +} + +# Output Azure Tenant ID +output "azure_tenant_id" { + description = "Azure Tenant ID." + value = data.azurerm_subscription.primary.tenant_id +} diff --git a/modules/github-ci/variables.tf b/modules/github-ci/variables.tf new file mode 100644 index 0000000..ab5b9de --- /dev/null +++ b/modules/github-ci/variables.tf @@ -0,0 +1,20 @@ +variable "repo_app_service_map" { + description = </resourceGroups//providers/Microsoft.Web/sites/\", + \"/subscriptions//resourceGroups//providers/Microsoft.Web/sites/\" + ], + \"owner/repo2\" = [ + \"/subscriptions//resourceGroups//providers/Microsoft.Web/sites/\" + ] + EOT + type = map(list(string)) +} + + +#variable "azure_tenant_id" { +# description = "The Tenant ID for Azure Active Directory." +# type = string +#}