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-oidc/.terraform-docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
formatter: "markdown"

version: ""

Comment on lines +3 to +4
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.

Setting version to an empty string may be treated as an invalid value by terraform-docs and can fail parsing/validation depending on the tool version. If you don’t want to pin a version, omit the field; otherwise set it to a valid version string.

Suggested change
version: ""

Copilot uses AI. Check for mistakes.
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
137 changes: 92 additions & 45 deletions modules/azure-oidc/README.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,29 @@
# Azure OIDC
<!-- BEGIN_TF_DOCS -->
# Azure OIDC Terraform Module

## Overview

This module creates an Azure AD application, service principal and role assignment for each application in the data file.
This Terraform module creates Azure AD applications, service principals, and role assignments for each application defined in the input data file. It supports federated credentials for GitHub Actions and other issuers.

> Note: not defining a scope in an application is equivalent to defining the scope of the subscription
> Note: Not defining a scope in an application is equivalent to defining the scope of the subscription.

## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_azuread"></a> [azuread](#requirement\_azuread) | ~> 2.15.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >3.0.0 |
## Main features
- Create multiple Azure AD applications and service principals.
- Assign custom roles and scopes to each application.
- Add federated credentials for GitHub Actions or custom issuers.
- Realistic configuration example.

## Providers
## Complete usage example

| Name | Version |
|------|---------|
| <a name="provider_azuread"></a> [azuread](#provider\_azuread) | ~> 2.15.0 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >3.0.0 |

## Resources

| Name | Type |
|------|------|
| [azuread_application.gh_oidc_ad_app](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application) | resource |
| [azuread_application_federated_identity_credential.gh_oidc_identity_credential](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application_federated_identity_credential) | resource |
| [azuread_service_principal.gh_oidc_service_principal](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/service_principal) | resource |
| [azurerm_role_assignment.gh_oidc_service_role_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azuread_client_config.current](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/client_config) | data source |
| [azurerm_subscription.primary](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source |

## Usage

### Set a module

```terraform
module "githuib-oidc" {
### Module usage
```hcl
module "github-oidc" {
source = "git::https://github.com/prefapp/tfm.git//modules/azure-oidc?ref=<version>"
data = yamldecode(file("<path_to_yaml_file>"
data = yamldecode(file("<path_to_yaml_file>"))
}
```

#### Example

```terraform
module "githuib-oidc" {
source = "git::https://github.com/prefapp/tfm.git//modules/azure-oidc?ref=v1.2.3"
data = yamldecode(file("github_oidc.yaml")
```

### Set a data file

### Example data file
```yaml
applications:
- name: app
Expand All @@ -74,8 +46,7 @@ applications:
issuer: "issuer_foo_foo"
```

#### Example

#### Realistic example
```yaml
app_registrations:
- name: service_repositories
Expand Down Expand Up @@ -107,3 +78,79 @@ app_registrations:
# scope:
# - "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # This is similar to not putting scope
```

## Notes
- If you do not define a scope, the subscription scope will be used by default.
- Federated credentials support GitHub Actions and custom issuers.
- Each application can have multiple roles, scopes, and federated credentials.

## File structure

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

## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_azuread"></a> [azuread](#requirement\_azuread) | ~> 2.15.0 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >3.0.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_azuread"></a> [azuread](#provider\_azuread) | ~> 2.15.0 |
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | >3.0.0 |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [azuread_application.gh_oidc_ad_app](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application) | resource |
| [azuread_application_federated_identity_credential.gh_oidc_identity_credential](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application_federated_identity_credential) | resource |
| [azuread_service_principal.gh_oidc_service_principal](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/service_principal) | resource |
| [azurerm_role_assignment.gh_oidc_service_role_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azuread_client_config.current](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/client_config) | data source |
| [azurerm_subscription.primary](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_data"></a> [data](#input\_data) | YAML data for configuring resources | `any` | n/a | yes |

## Outputs

No outputs.

## Examples

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

- [basic](https://github.com/prefapp/tfm/tree/main/modules/azure-oidc/_examples/basic) - OIDC and federated credentials configuration for workloads (e.g., GitHub Actions).

## Resources and support

- [Official Azure AD Application documentation](https://learn.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals)
- [Terraform reference for azuread\_application](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application)
- [Terraform reference for azuread\_application\_federated\_identity\_credential](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application_federated_identity_credential)
- [Terraform reference for azurerm\_role\_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment)

## Support

For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues).
<!-- END_TF_DOCS -->
21 changes: 21 additions & 0 deletions modules/azure-oidc/_examples/basic/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module "azure_oidc" {
source = "../../"

data = {
app_registrations = [
{
name = "service_repositories"
roles = ["AcrPush", "AcrPull"]
scope = [
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/providers/Microsoft.ContainerRegistry/registries/foo-registry"
]
federated_credentials = [
{
subject = "repository_owner:prefapp"
issuer = "https://token.actions.githubusercontent.com"
}
]
}
]
}
}
11 changes: 11 additions & 0 deletions modules/azure-oidc/_examples/basic/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
data:
app_registrations:
- name: service_repositories
roles:
- AcrPush
- AcrPull
scope:
- /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/providers/Microsoft.ContainerRegistry/registries/foo-registry
federated_credentials:
- subject: repository_owner:prefapp
issuer: https://token.actions.githubusercontent.com
Comment on lines +1 to +11
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 YAML example wraps the input under a data: key, but the module examples pass data as the object that contains app_registrations directly. Unless the intended usage is yamldecode(file(...)).data, this data: wrapper will cause a shape mismatch. Consider removing the wrapper so the YAML root is app_registrations: to match the documented module input.

Suggested change
data:
app_registrations:
- name: service_repositories
roles:
- AcrPush
- AcrPull
scope:
- /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/providers/Microsoft.ContainerRegistry/registries/foo-registry
federated_credentials:
- subject: repository_owner:prefapp
issuer: https://token.actions.githubusercontent.com
app_registrations:
- name: service_repositories
roles:
- AcrPush
- AcrPull
scope:
- /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/foo/providers/Microsoft.ContainerRegistry/registries/foo-registry
federated_credentials:
- subject: repository_owner:prefapp
issuer: https://token.actions.githubusercontent.com

Copilot uses AI. Check for mistakes.
16 changes: 16 additions & 0 deletions modules/azure-oidc/docs/footer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
## Examples

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

- [basic](https://github.com/prefapp/tfm/tree/main/modules/azure-oidc/_examples/basic) - OIDC and federated credentials configuration for workloads (e.g., GitHub Actions).

## Resources and support

- [Official Azure AD Application documentation](https://learn.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals)
- [Terraform reference for azuread_application](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application)
- [Terraform reference for azuread_application_federated_identity_credential](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/application_federated_identity_credential)
- [Terraform reference for azurerm_role_assignment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment)

## Support

For issues, questions, or contributions related to this module, please visit the [repository's issue tracker](https://github.com/prefapp/tfm/issues).
98 changes: 98 additions & 0 deletions modules/azure-oidc/docs/header.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Azure OIDC Terraform Module

## Overview

This Terraform module creates Azure AD applications, service principals, and role assignments for each application defined in the input data file. It supports federated credentials for GitHub Actions and other issuers.

> Note: Not defining a scope in an application is equivalent to defining the scope of the subscription.

## Main features
- Create multiple Azure AD applications and service principals.
- Assign custom roles and scopes to each application.
- Add federated credentials for GitHub Actions or custom issuers.
- Realistic configuration example.

## Complete usage example

### Module usage
```hcl
module "github-oidc" {
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.

Using a hyphen in the Terraform module block name makes it awkward to reference (e.g., module.github-oidc is parsed as subtraction in expressions). Prefer an underscore-only name like github_oidc to avoid reference issues.

Suggested change
module "github-oidc" {
module "github_oidc" {

Copilot uses AI. Check for mistakes.
source = "git::https://github.com/prefapp/tfm.git//modules/azure-oidc?ref=<version>"
data = yamldecode(file("<path_to_yaml_file>"))
}
```

### Example data file
```yaml
applications:
- name: app
roles:
- role1
- role2
scope:
- scope1
- scope2
federated_credentials:
Comment on lines +27 to +35
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 example uses the top-level key applications, but the realistic example (and the _examples/basic config) use app_registrations. This inconsistency will confuse users and can lead to invalid inputs. Align the docs to a single expected input shape (preferably app_registrations if that’s what the module consumes).

Copilot uses AI. Check for mistakes.
- subject: "subject_claim_foo:my_repo_foo"
issuer: "issuer_foo"
- subject: "subject_claim_bar:my_repo_bar"
issuer: "issuer_bar"
- name: app2
roles:
- role1
federated_credentials:
- subject: "my_repo_foo_foo"
issuer: "issuer_foo_foo"
```

#### Realistic example
```yaml
app_registrations:
- name: service_repositories
roles:
- AcrPush
- AcrPull
scope:
- "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/foo/providers/Microsoft.ContainerRegistry/registries/foo-registries"
- "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/bar/providers/Microsoft.ContainerRegistry/registries/bar-registries"
federated_credentials:
- subject: "repository_owner:prefapp"
issuer: "https://token.actions.githubusercontent.com"
- name: state_repositorie
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.

Correct the typo state_repositorie to state_repositories.

Suggested change
- name: state_repositorie
- name: state_repositories

Copilot uses AI. Check for mistakes.
roles:
- AcrPush
scope:
- "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/foo/providers/Microsoft.ContainerRegistry/registries/foo-registries"
federated_credentials:
- subject: "repository_owner:prefapp"
issuer: "https://token.actions.githubusercontent.com"
- name: infra_repositorie
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.

Correct the typo infra_repositorie to infra_repositories.

Suggested change
- name: infra_repositorie
- name: infra_repositories

Copilot uses AI. Check for mistakes.
roles:
- Contributor
federated_credentials:
- subject: "my_repo_foo"
issuer: "issuer_foo"
- subject: "my_repo_bar"
issuer: "issuer_bar"
# scope:
# - "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # This is similar to not putting scope
```

## Notes
- If you do not define a scope, the subscription scope will be used by default.
- Federated credentials support GitHub Actions and custom issuers.
- Each application can have multiple roles, scopes, and federated credentials.

## File structure

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