Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions modules/azure-mi/.terraform-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
formatter: "markdown" # this is required

version: ""

header-from: docs/header.md
footer-from: docs/footer.md

recursive:
enabled: false
path: modules
include-main: true

sections:
hide: []
show: []

content: ""

output:
file: "README.md"
mode: inject
template: |-
<!-- BEGIN_TF_DOCS -->
{{ .Content }}
<!-- END_TF_DOCS -->

output-values:
enabled: false
from: ""

sort:
enabled: true
by: name

settings:
anchor: true
color: true
default: true
description: false
escape: true
hide-empty: false
html: true
indent: 2
lockfile: true
read-comments: true
required: true
sensitive: true
type: true
148 changes: 106 additions & 42 deletions modules/azure-mi/README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,27 @@
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.7.5 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | = 4.16.0 |
<!-- BEGIN_TF_DOCS -->
# Azure Managed Identity Terraform Module

## Resources
## Overview

| Name | Type |
|------|------|
| [azurerm_resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group.html) | data resource (only when `tags from resource group` is enabled) |
| [azurerm_user_assigned_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | source |
| [azurerm_role_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/2.62.1/docs/resources/role_assignment) | source |
| [azurerm_federated_identity_credential](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/federated_identity_credential) | source (only when `federated_credentials` is not empty) |

## Inputs
This Terraform module allows you to create and manage a User Assigned Managed Identity in Azure, with support for:
- Custom RBAC role assignments.
- Federated credentials for GitHub, Kubernetes, or other issuers.
- Tag inheritance from the resource group.
- Flexible audience configuration for federated credentials.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| name | The name of the Managed Identity | `string` | n/a | yes |
| resource_group | The name of the resource group in which to create the Managed Identity | `string` | n/a | yes |
| location | The location in which to create the Managed Identity | `string` | n/a | yes |
| tags | A mapping of tags to assign to the resource | `map(string)` | n/a | no |
| tags_from_rg | If true, the tags from the resource group will be inherited exclusively | `bool` | `false` | no |
| rbac | A list of role-based access control (RBAC) policies to apply to the Managed Identity | <pre>list(object({<br> name: string (required)<br> scope: string (required)<br> roles: list(string) (required)<br>}))</pre> | n/a | yes |
| federated_credentials | A list of federated credentials to assign to the Managed Identity, posible types are:<br><br>**kubernetes**: `issuer`, `namespace` and `service_account_name`<br>- `issuer`: The cluster issuer<br>- `namespace`: The namespace of the service account<br>- `service_account_name`: The name of the service account<br><br>**github**: `issuer`, `organization`, `repository` and `entity`<br>- `issuer`: The github issuer<br>- `organization`: The github organization<br>- `repository`: The github repository<br>- `entity`: The github entity \|Optional value, if not provided, the entity will be the repository. For other scenarios, the entity should be provided:<br>&nbsp;&nbsp;- environment: `environment:foo_enviroment`<br>&nbsp;&nbsp;- tags: `ref:refs/tags/foo_tag`<br>&nbsp;&nbsp;- branch: `ref:refs/heads/foo_branch`<br>&nbsp;&nbsp;- commit: `ref:refs/commits/foo_commit`<br><br>**other**: `issuer` and `subject`<br>- `issuer`: The issuer<br>- `subject`: The subject | <pre>list(object({<br> name: string (required)<br> type: string (required) - **kubernetes** \|\| **github** \|\| **other**<br> issuer: string (required only when type is **kubernetes** or **other**, when type is **github** is optional because the default is `https://token.actions.githubusercontent.com`)<br> namespace: string (required only when the type is **kubernetes**)<br> service_account_name: string (required only when the type is **kubernetes**)<br> organization: string (required only when the type is **github**)<br> repository: string (required only when the type is **github**)<br> entity: string (required only when the type is **github** and the entity is not the repository)<br> subject: string (required only when the type is **other**)<br>}))</pre> | `[]` | no |
| audience | The audience of the federated identity credential | `list(string)` | `["api://AzureADTokenExchange"]` | no |
## Main features
- Create a managed identity with custom tags and location.
- Assign multiple RBAC roles at different scopes.
- Add federated credentials for GitHub Actions, Kubernetes service accounts, or custom issuers.
- Realistic configuration example.

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_user_assigned_identity_id"></a> [user_assigned_identity_id](#output\_user\_assigned\_identity\_id) | The ID of the User Assigned Identity. |
| <a name="output\_user\_assigned\_identity\_id"></a> [user\_assigned\_identity\_id](#output\\_user\\_assigned\\_identity\\_id) | The ID of the User Assigned Identity. |
Comment on lines 18 to +22
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This manual Outputs section in the header conflicts with the terraform-docs autogenerated Outputs section later in the README (which lists id). Keeping both will drift over time and is already inconsistent. Prefer removing the manual Outputs section from the custom header (or make it match the actual output names), and rely on terraform-docs for Outputs rendering.

Copilot uses AI. Check for mistakes.

## Example
## Complete usage example

### HCL
```hcl
Expand Down Expand Up @@ -90,29 +73,28 @@ federated_credentials = [
subject = "other"
}
]

```

### Yaml
### YAML
```yaml
name: xxx
resource_group_name: xxx
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The README YAML example uses resource_group_name, but the documented input name is resource_group (see Inputs table). Update the YAML example to use resource_group to match the actual module interface.

Suggested change
resource_group_name: xxx
resource_group: xxx

Copilot uses AI. Check for mistakes.
location: xxx
tags:
foo: bar
foo: bar
# tags_from_rg: true # Will inherit the tags from the resource group exclusively
rbac: # 1-n
rbac:
- name: foo
scope: scope-foo
roles:
- xxx
- xxx
- name: bar
scope: scope-bar
roles: # 1-n
- xxx
- yyy
- zzz
federated_credentials: # {} | 0-20
roles:
- xxx
- yyy
- zzz
federated_credentials:
- name: foo-github
type: github
organization: foo
Expand All @@ -128,3 +110,85 @@ federated_credentials: # {} | 0-20
issuer: https://example.com
subject: other
```

## Notes
- You can use `tags_from_rg` to inherit tags exclusively from the resource group.
- Federated credentials support GitHub Actions, Kubernetes, and custom issuers.
- RBAC assignments can be defined for multiple scopes and roles.

## File structure

```
.
├── main.tf
├── variables.tf
├── outputs.tf
├── README.md
├── CHANGELOG.md
└── docs/
├── header.md
└── footer.md
```

## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.7.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | ~> 4.16.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | ~> 4.16.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azurerm_federated_identity_credential.that](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/federated_identity_credential) | resource |
| [azurerm_key_vault_access_policy.access_policy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_access_policy) | resource |
| [azurerm_role_assignment.that](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_user_assigned_identity.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) | resource |
| [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) | data source |
| [azurerm_resource_group.resource_group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/resource_group) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_access_policies"></a> [access\_policies](#input\_access\_policies) | List of access policies for the Key Vault | <pre>list(object({<br/> key_vault_id = string<br/> key_permissions = optional(list(string), [])<br/> secret_permissions = optional(list(string), [])<br/> certificate_permissions = optional(list(string), [])<br/> storage_permissions = optional(list(string), [])<br/> }))</pre> | `[]` | no |
| <a name="input_audience"></a> [audience](#input\_audience) | The audience for the federated identity credential. | `list(string)` | <pre>[<br/> "api://AzureADTokenExchange"<br/>]</pre> | no |
| <a name="input_federated_credentials"></a> [federated\_credentials](#input\_federated\_credentials) | A list of objects containing the federated credentials to assign to the User Assigned Identity. | <pre>list(object({<br/> name = string<br/> type = string<br/> issuer = optional(string)<br/> namespace = optional(string)<br/> service_account_name = optional(string)<br/> organization = optional(string)<br/> repository = optional(string)<br/> entity = optional(string)<br/> subject = optional(string)<br/> }))</pre> | `[]` | no |
| <a name="input_location"></a> [location](#input\_location) | The location/region where the User Assigned Identity should be created. | `string` | n/a | yes |
| <a name="input_name"></a> [name](#input\_name) | The name of the User Assigned Identity. | `string` | n/a | yes |
| <a name="input_rbac"></a> [rbac](#input\_rbac) | A list of objects containing the RBAC roles to assign to the User Assigned Identity. | <pre>list(object({<br/> name = string<br/> scope = string<br/> roles = list(string)<br/> }))</pre> | n/a | yes |
| <a name="input_resource_group"></a> [resource\_group](#input\_resource\_group) | The name of the Resource Group. | `string` | n/a | yes |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the User Assigned Identity. | `map(string)` | <pre>{<br/> "name": "value"<br/>}</pre> | no |
| <a name="input_tags_from_rg"></a> [tags\_from\_rg](#input\_tags\_from\_rg) | If true, the User Assigned Identity will inherit the tags from the Resource Group. | `bool` | `false` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_id"></a> [id](#output\_id) | # OUTPUTS SECTION User Assigned Identity |
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The output description # OUTPUTS SECTION User Assigned Identity is not a useful consumer-facing description and reads like a placeholder. Update the output description in the module’s outputs.tf (so terraform-docs renders it correctly) to something like: 'The ID of the User Assigned Identity.'

Suggested change
| <a name="output_id"></a> [id](#output\_id) | # OUTPUTS SECTION User Assigned Identity |
| <a name="output_id"></a> [id](#output\_id) | The ID of the User Assigned Identity. |

Copilot uses AI. Check for mistakes.

## Examples

For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-mi/_examples):

- [basic](https://github.com/prefapp/tfm/tree/main/modules/azure-mi/_examples/basic) - User-assigned managed identity with basic configuration.

## Resources and support

- [Official Azure Managed Identities documentation](https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview)
- [Terraform reference for azurerm\_user\_assigned\_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity)
- [Community support](https://github.com/prefapp/terraform-modules/discussions)

Need help? Open an issue or join the Prefapp community.
<!-- END_TF_DOCS -->
32 changes: 32 additions & 0 deletions modules/azure-mi/_examples/basic/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module "azure_mi" {
source = "../../"

name = "example-mi"
resource_group = "example-rg"
location = "westeurope"

tags_from_rg = false
tags = {
environment = "dev"
}

rbac = [
{
name = "example-rbac"
scope = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg"
roles = ["Reader"]
}
]

access_policies = []

federated_credentials = [
{
name = "example-github"
type = "github"
organization = "example-org"
repository = "example-repo"
entity = "ref:refs/heads/main"
}
]
}
22 changes: 22 additions & 0 deletions modules/azure-mi/_examples/basic/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: example-mi
resource_group: example-rg
location: westeurope

tags_from_rg: false
tags:
environment: dev

rbac:
- name: example-rbac
scope: /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-rg
roles:
- Reader

access_policies: []

federated_credentials:
- name: example-github
type: github
organization: example-org
repository: example-repo
entity: ref:refs/heads/main
13 changes: 13 additions & 0 deletions modules/azure-mi/docs/footer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
## Examples

For detailed examples, refer to the [module examples](https://github.com/prefapp/tfm/tree/main/modules/azure-mi/_examples):

- [basic](https://github.com/prefapp/tfm/tree/main/modules/azure-mi/_examples/basic) - User-assigned managed identity with basic configuration.

## Resources and support

- [Official Azure Managed Identities documentation](https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview)
- [Terraform reference for azurerm_user_assigned_identity](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity)
- [Community support](https://github.com/prefapp/terraform-modules/discussions)

Need help? Open an issue or join the Prefapp community.
Loading