diff --git a/modules/azure-mi/.terraform-docs.yml b/modules/azure-mi/.terraform-docs.yml new file mode 100644 index 000000000..bce3ca3a9 --- /dev/null +++ b/modules/azure-mi/.terraform-docs.yml @@ -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: |- + + {{ .Content }} + + +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 \ No newline at end of file diff --git a/modules/azure-mi/README.md b/modules/azure-mi/README.md index 8acfa8c59..c9b2f7ede 100644 --- a/modules/azure-mi/README.md +++ b/modules/azure-mi/README.md @@ -1,44 +1,27 @@ -## Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.7.5 | - -## Providers - -| Name | Version | -|------|---------| -| [azurerm](#provider\_azurerm) | = 4.16.0 | + +# 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 |
list(object({
name: string (required)
scope: string (required)
roles: list(string) (required)
}))
| n/a | yes | -| federated_credentials | A list of federated credentials to assign to the Managed Identity, posible types are:

**kubernetes**: `issuer`, `namespace` and `service_account_name`
- `issuer`: The cluster issuer
- `namespace`: The namespace of the service account
- `service_account_name`: The name of the service account

**github**: `issuer`, `organization`, `repository` and `entity`
- `issuer`: The github issuer
- `organization`: The github organization
- `repository`: The github repository
- `entity`: The github entity \|Optional value, if not provided, the entity will be the repository. For other scenarios, the entity should be provided:
  - environment: `environment:foo_enviroment`
  - tags: `ref:refs/tags/foo_tag`
  - branch: `ref:refs/heads/foo_branch`
  - commit: `ref:refs/commits/foo_commit`

**other**: `issuer` and `subject`
- `issuer`: The issuer
- `subject`: The subject |
list(object({
name: string (required)
type: string (required) - **kubernetes** \|\| **github** \|\| **other**
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`)
namespace: string (required only when the type is **kubernetes**)
service_account_name: string (required only when the type is **kubernetes**)
organization: string (required only when the type is **github**)
repository: string (required only when the type is **github**)
entity: string (required only when the type is **github** and the entity is not the repository)
subject: string (required only when the type is **other**)
}))
| `[]` | 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 | |------|-------------| -| [user_assigned_identity_id](#output\_user\_assigned\_identity\_id) | The ID of the User Assigned Identity. | +| [user\_assigned\_identity\_id](#output\\_user\\_assigned\\_identity\\_id) | The ID of the User Assigned Identity. | -## Example +## Complete usage example ### HCL ```hcl @@ -90,29 +73,28 @@ federated_credentials = [ subject = "other" } ] - ``` -### Yaml +### YAML ```yaml name: xxx resource_group_name: xxx 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 @@ -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 | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.7.0 | +| [azurerm](#requirement\_azurerm) | ~> 4.16.0 | + +## Providers + +| Name | Version | +|------|---------| +| [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 | +|------|-------------|------|---------|:--------:| +| [access\_policies](#input\_access\_policies) | List of access policies for the Key Vault |
list(object({
key_vault_id = string
key_permissions = optional(list(string), [])
secret_permissions = optional(list(string), [])
certificate_permissions = optional(list(string), [])
storage_permissions = optional(list(string), [])
}))
| `[]` | no | +| [audience](#input\_audience) | The audience for the federated identity credential. | `list(string)` |
[
"api://AzureADTokenExchange"
]
| no | +| [federated\_credentials](#input\_federated\_credentials) | A list of objects containing the federated credentials to assign to the User Assigned Identity. |
list(object({
name = string
type = string
issuer = optional(string)
namespace = optional(string)
service_account_name = optional(string)
organization = optional(string)
repository = optional(string)
entity = optional(string)
subject = optional(string)
}))
| `[]` | no | +| [location](#input\_location) | The location/region where the User Assigned Identity should be created. | `string` | n/a | yes | +| [name](#input\_name) | The name of the User Assigned Identity. | `string` | n/a | yes | +| [rbac](#input\_rbac) | A list of objects containing the RBAC roles to assign to the User Assigned Identity. |
list(object({
name = string
scope = string
roles = list(string)
}))
| n/a | yes | +| [resource\_group](#input\_resource\_group) | The name of the Resource Group. | `string` | n/a | yes | +| [tags](#input\_tags) | A mapping of tags to assign to the User Assigned Identity. | `map(string)` |
{
"name": "value"
}
| no | +| [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 | +|------|-------------| +| [id](#output\_id) | # OUTPUTS SECTION User Assigned Identity | + +## 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. + \ No newline at end of file diff --git a/modules/azure-mi/_examples/basic/main.tf b/modules/azure-mi/_examples/basic/main.tf new file mode 100644 index 000000000..ea435c045 --- /dev/null +++ b/modules/azure-mi/_examples/basic/main.tf @@ -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" + } + ] +} diff --git a/modules/azure-mi/_examples/basic/values.yaml b/modules/azure-mi/_examples/basic/values.yaml new file mode 100644 index 000000000..87e304995 --- /dev/null +++ b/modules/azure-mi/_examples/basic/values.yaml @@ -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 \ No newline at end of file diff --git a/modules/azure-mi/docs/footer.md b/modules/azure-mi/docs/footer.md new file mode 100644 index 000000000..a60d6376a --- /dev/null +++ b/modules/azure-mi/docs/footer.md @@ -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. \ No newline at end of file diff --git a/modules/azure-mi/docs/header.md b/modules/azure-mi/docs/header.md new file mode 100644 index 000000000..64fe3a562 --- /dev/null +++ b/modules/azure-mi/docs/header.md @@ -0,0 +1,130 @@ +# Azure Managed Identity Terraform Module + +## Overview + +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. + +## 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 | +|------|-------------| +| [user_assigned_identity_id](#output\_user\_assigned\_identity\_id) | The ID of the User Assigned Identity. | + +## Complete usage example + +### HCL +```hcl +name = "xxx" +resource_group = "xxx" +location = "xxx" +tags = { + foo = "bar" +} +# tags_from_rg = true # Will inherit the tags from the resource group exclusively +rbac = [ + { + name = "foo" + scope = "scope-foo" + roles = [ + "xxx" + ] + }, + { + name = "bar" + scope = "scope-bar" + roles = [ + "xxx", + "yyy", + "zzz" + ] + } +] + +federated_credentials = [ + { + name = "foo-github" + type = "github" + organization = "foo" + repository = "bar" + entity = "baz" + }, + { + name = "foo-kubernetes" + type = "kubernetes" + issuer = "https://kubernetes.default.svc.cluster.local" + namespace = "foo" + service_account_name = "bar" + }, + { + name = "other" + type = "other" + issuer = "https://example.com" + subject = "other" + } +] +``` + +### YAML +```yaml +name: xxx +resource_group_name: xxx +location: xxx +tags: + foo: bar +# tags_from_rg: true # Will inherit the tags from the resource group exclusively +rbac: + - name: foo + scope: scope-foo + roles: + - xxx + - name: bar + scope: scope-bar + roles: + - xxx + - yyy + - zzz +federated_credentials: + - name: foo-github + type: github + organization: foo + repository: bar + entity: baz + - name: foo-kubernetes + type: kubernetes + issuer: https://kubernetes.default.svc.cluster.local + namespace: foo + service_account_name: bar + - name: other + type: other + 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 +``` \ No newline at end of file