Skip to content

A module that uses the Azuredevops, and AzureRm to create a user assigned managed identity (mi), scope that mi to a subscription with a role of your choice, it then configures OIDC with Azure DevOps and adds that newly created mi to a Azure DevOps service connection for use. Use script for Azure DevOps Org id ๐Ÿš€

License

Notifications You must be signed in to change notification settings

libre-devops/terraform-azuredevops-federated-managed-identity-connection

Repository files navigation

data "azurerm_client_config" "current" {}

data "azurerm_subscription" "current" {}

data "azuredevops_project" "project_id" {
  name = var.azuredevops_project_name
}

locals {
  default_managed_identity_name             = var.managed_identity_name != null ? var.managed_identity_name : "msi-azdo-${var.azuredevops_project_name}-${var.azuredevops_organization_guid}"
  default_managed_identity_description      = var.managed_identity_description != null ? var.managed_identity_description : "This managed identity is for the federated credential of Azure DevOps of the project ${var.azuredevops_project_name}, in the organization ${var.azuredevops_organization_name} with guid ${var.azuredevops_organization_guid}"
  default_federated_credential_display_name = var.federated_credential_display_name != null ? var.federated_credential_display_name : "oidc-wlfid-${local.default_managed_identity_name}"
}

module "rg" {
  source = "libre-devops/rg/azurerm"

  count = var.rg_id == null ? 1 : 0

  rg_name  = var.rg_name
  location = var.location
  tags     = var.tags
}

locals {
  rg_parts           = var.rg_id != null ? split("/", var.rg_id) : null
  rg_name            = local.rg_parts != null ? local.rg_parts[4] : null
  rg_subscription_id = local.rg_parts != null ? local.rg_parts[2] : null
}

resource "azurerm_user_assigned_identity" "uid" {
  name                = local.default_managed_identity_name
  resource_group_name = local.rg_name != null ? local.rg_name : module.rg[0].rg_name
  location            = var.location
  tags                = var.tags
}

resource "azuredevops_serviceendpoint_azurerm" "azure_devops_service_endpoint_azurerm" {
  depends_on                             = [azurerm_role_assignment.assign_spn_to_subscription[0]]
  project_id                             = data.azuredevops_project.project_id.id
  service_endpoint_name                  = var.managed_identity_name != null ? var.managed_identity_name : local.default_managed_identity_name
  description                            = var.managed_identity_description
  service_endpoint_authentication_scheme = "WorkloadIdentityFederation"

  credentials {
    serviceprincipalid = azurerm_user_assigned_identity.uid.client_id
  }

  azurerm_spn_tenantid      = data.azurerm_client_config.current.tenant_id
  azurerm_subscription_id   = data.azurerm_subscription.current.subscription_id
  azurerm_subscription_name = data.azurerm_subscription.current.display_name
}

resource "azurerm_role_assignment" "assign_spn_to_subscription" {
  count                = var.attempt_assign_role_to_spn == true ? 1 : 0
  principal_id         = azurerm_user_assigned_identity.uid.principal_id
  scope                = data.azurerm_subscription.current.id
  role_definition_name = var.role_definition_name_to_assign
}

resource "azurerm_federated_identity_credential" "federated_credential" {
  name                = local.default_federated_credential_display_name
  resource_group_name = azurerm_user_assigned_identity.uid.resource_group_name
  parent_id           = azurerm_user_assigned_identity.uid.id
  audience            = var.federated_credential_audiences
  issuer              = azuredevops_serviceendpoint_azurerm.azure_devops_service_endpoint_azurerm.workload_identity_federation_issuer
  subject             = azuredevops_serviceendpoint_azurerm.azure_devops_service_endpoint_azurerm.workload_identity_federation_subject
}

Requirements

Name Version
azuredevops >=1.0.1

Providers

Name Version
azuredevops >=1.0.1
azurerm n/a

Modules

Name Source Version
rg libre-devops/rg/azurerm n/a

Resources

Name Type
azuredevops_serviceendpoint_azurerm.azure_devops_service_endpoint_azurerm resource
azurerm_federated_identity_credential.federated_credential resource
azurerm_role_assignment.assign_spn_to_subscription resource
azurerm_user_assigned_identity.uid resource
azuredevops_project.project_id data source
azurerm_client_config.current data source
azurerm_subscription.current data source

Inputs

Name Description Type Default Required
attempt_assign_role_to_spn Whether or not to attempt to assign a role to the SPN to the subscription. This is actually needed, so defaults to true bool true no
azuredevops_organization_guid The unique ID of your Azure DevOps organisation string n/a yes
azuredevops_organization_name The name of your Azure DevOps organization string n/a yes
azuredevops_project_name The name of your Azure DevOps project you want to configure the federated cred for string n/a yes
federated_credential_audiences The audience for the credential, set to the default for Azure DevOps list(string)
[
"api://AzureADTokenExchange"
]
no
federated_credential_display_name The display name of your federated credential in AzureAD/Entra for ID string null no
location The location for this resource to be put in string "uksouth" no
managed_identity_description The description of the service principal string null no
managed_identity_name The name of the service principal string null no
rg_id The id of a resource group, supplying this value stops the module from creating a resource group, defaults to null as created a resource group is the default behaviour string null no
rg_name The name of the resource group, this module creates a resource group for you, so please supply a unique name string null no
role_definition_name_to_assign The role definition needed to setup SPN, for security reasons, defautls to Reader string "Reader" no
tags A map of the tags to use on the resources that are deployed with this module. map(string) {} no

Outputs

Name Description
service_endpoint_id The id of the service endpoint
service_endpoint_name The project name of the service endpoint is made with
service_endpoint_project_id The project id of the service endpoint is made with
service_endpoint_service_principal_id The service principal id service endpoint is made with
user_assigned_managed_identity_id The resource id of the managed identity
user_assigned_managed_identity_object_id The object id id of the managed identity
user_assigned_managed_identity_tenant_id The tenant id of the managed identity
workload_identity_federation_issuer The issuer for the workload issuer
workload_identity_federation_subject The subject for the workload federation

About

A module that uses the Azuredevops, and AzureRm to create a user assigned managed identity (mi), scope that mi to a subscription with a role of your choice, it then configures OIDC with Azure DevOps and adds that newly created mi to a Azure DevOps service connection for use. Use script for Azure DevOps Org id ๐Ÿš€

Resources

License

Stars

Watchers

Forks

Packages

No packages published