Skip to content

Commit

Permalink
Initial module structure (#1)
Browse files Browse the repository at this point in the history
* Initial module structure

* Removed terraform checks, fixed dependabot directory
  • Loading branch information
Retoxx-dev authored Jul 19, 2024
1 parent edf3f2d commit d5ebd87
Show file tree
Hide file tree
Showing 12 changed files with 355 additions and 83 deletions.
2 changes: 1 addition & 1 deletion .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
version: 2
updates:
- package-ecosystem: "terraform" # See documentation for possible values
directory: "/terraform/"
directory: "./"
assignees:
- dtykalowski-tsh
reviewers:
Expand Down
18 changes: 0 additions & 18 deletions .github/workflows/terraform-checks.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion .markdownlint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ MD032: true
# MD033/no-inline-html - Inline HTML
MD033:
# Allowed elements
allowed_elements: ["p", "img"]
allowed_elements: ["p", "img", "a", "br", "pre"]

# MD034/no-bare-urls - Bare URL used
MD034: true
Expand Down
146 changes: 116 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,138 @@
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSlIC9FYD-n7m_ASko0O_D11MeFdVV-CtFtqw&s">
</p>

# Terraform Sample Module by TSH
# Azure Role Assignment Terraform Module

This is template for sample module used within Terraform.
## Assign roles to users, groups and service principals

## How To Start
This Terraform module assigns `BUILT IN` roles to users, groups and service principals.

```bash
task install:tools
# create your module
# optionally
pre-commit run --all-files
## Prerequisites

Following permissions are needed to use some features this module provides:

- `User.Read.All` or `Directory.Read.All` for assigning roles to users.

- `Group.Read.All` or `Directory.Read.All` for assigning roles to groups.

- `Application.Read.All` or `Directory.Read.All` for assigning roles to service principals.

## Usage

### Assign roles to users

```terraform
module "role_assignments" {
source = "TheSoftwareHouse/role-assignment/azurerm"
version = "1.0.0"
scope = azurerm_resource_group.this.id
role_assignments = [
{
user_principal_names = ["[email protected]", "[email protected]"]
role_names = ["Reader", "Web Plan Contributor"]
}
]
}
```

### Assign roles to groups

```terraform
module "role_assignments" {
source = "TheSoftwareHouse/role-assignment/azurerm"
version = "1.0.0"
scope = azurerm_resource_group.this.id
role_assignments = [
{
group_names = ["group1", "group2", "group3"]
role_names = ["Reader", "Web Plan Contributor"]
}
]
}
```

## Quality Assurance
### Assign roles to service principals

```terraform
module "role_assignments" {
source = "TheSoftwareHouse/role-assignment/azurerm"
version = "1.0.0"
- make sure all checks pass before merging to main
- if you are sure code is ready for next release, make sure you maintain changelog for introduced changes
- in order to bootstrap module, use `terraform-main` repository and create GitHub repository from there in Terraform
- try to remember about consistent set of tags, they can be choosen and adjusted as needed, you can find sample set in `terraform-main`
- as for prefixes, try to stick with standard below (if possible, there are cases where name would be too long or it's enforced by cloud provider)
scope = azurerm_resource_group.this.id
```hcl
locals {
project_name = short_name
environment = prd
name_prefix = "${local.project_name}-${local.environment}"
role_assignments = [
{
sp_names = ["spname1", "spname2", "spname3"]
role_names = ["Reader", "Web Plan Contributor"]
}
]
}
```

- while handling outputs, remember to stick to original names e.g. module.vpc.vpc_id, in case there are multiple components, namespace each of outputs in it's source module name e.g. module.cluster.vpc.vpc_id and module.cluster.eks.oidc_issuer_url
- remember to split resources between files, either by resource types (e.g. s3.tf, ssm.tf, vpc.tf) or set of resources for specific purpose (eg. security_hub.tf).
### Assign roles to service principals but with principal ids

```terraform
module "role_assignments" {
source = "TheSoftwareHouse/role-assignment/azurerm"
version = "1.0.0"
scope = azurerm_resource_group.this.id
role_assignments = [
{
principal_ids = ["00000000-0000-0000-0000-000000000000"]
role_names = ["Reader", "Web Plan Contributor"]
}
]
}
```

For the full usage, please refer to the [full example](./examples/role_assignment_complete).

<!-- BEGIN_TF_DOCS -->
## Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5 |
| <a name="requirement_azuread"></a> [azuread](#requirement\_azuread) | >=2.53 |
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | >=3.113 |

## Providers

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

### 0.0.1
## Modules

- initial version, allows to create simple infrastructure
No modules.

### 0.0.2
## Resources

- added possibility to customise tags, by default they are empty so it's safe to upgrade (backwards compatible)
| Name | Type |
|------|------|
| [azurerm_role_assignment.group](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.principal_id](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.service_principal](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.user](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azuread_group.group](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/group) | data source |
| [azuread_service_principal.sp](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/service_principal) | data source |
| [azuread_user.user](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/user) | data source |

### 0.0.3
## Inputs

- adapted to new provider version, changed required version
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_role_assignments"></a> [role\_assignments](#input\_role\_assignments) | A list of role assignments to be created. | <pre>list(object({<br> group_names = optional(list(string), [])<br> user_principal_names = optional(list(string), [])<br> service_principal_names = optional(list(string), [])<br> principal_ids = optional(list(string), [])<br> role_names = list(string)<br> }))</pre> | n/a | yes |
| <a name="input_scope"></a> [scope](#input\_scope) | The scope at which the role assignments should be applied. | `string` | n/a | yes |

## Copyrights
## Outputs

2024 The Software House - All rights reserved
No outputs.
<!-- END_TF_DOCS -->
14 changes: 14 additions & 0 deletions data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
data "azuread_group" "this" {
for_each = { for idx, assignment in local.group_assignments : idx => assignment if assignment.principal_type == "Group" }
display_name = each.value.principal_name
}

data "azuread_user" "this" {
for_each = { for idx, assignment in local.user_assignments : idx => assignment if assignment.principal_type == "User" }
user_principal_name = each.value.principal_name
}

data "azuread_service_principal" "this" {
for_each = { for idx, assignment in local.sp_assignments : idx => assignment if assignment.principal_type == "ServicePrincipal" }
display_name = each.value.principal_name
}
56 changes: 56 additions & 0 deletions examples/role_assignment_complete/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Azure Role Assignment Module

Terraform module that assigns `BUILT IN` IAM roles to groups, service principals and users.

## Usage

```terraform
provider "azurerm" {
features {}
}
provider "azuread" {}
resource "azurerm_resource_group" "this" {
name = "rg-example"
location = "West Europe"
}
module "role_assignments" {
source = "TheSoftwareHouse/role-assignment/azurerm"
version = "1.0.0"
scope = azurerm_resource_group.this.id
role_assignments = [
{
user_principal_names = ["[email protected]", "[email protected]"]
role_names = ["Contributor", "Reader"]
},
{
group_names = ["Group1"]
role_names = ["Reader"]
},
{
service_principal_names = ["test"]
role_names = ["Contributor"]
},
{
principal_ids = ["00000000-0000-0000-0000-000000000000"]
role_names = ["Reader"]
}
]
}
```

## Terraform

To run this example you need to execute:

```bash
terraform init
terraform plan
terraform apply
```

You can destroy created resources with `terraform destroy`.
52 changes: 52 additions & 0 deletions examples/role_assignment_complete/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
terraform {
required_version = ">= 1.5"

required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">=3.113"
}

azuread = {
source = "hashicorp/azuread"
version = ">=2.53"
}
}
}

provider "azurerm" {
features {}
}

provider "azuread" {}

resource "azurerm_resource_group" "this" {
name = "rg-example"
location = "West Europe"
}

module "role_assignments" {
#checkov:skip=CKV_TF_1: commit hash isn't needed as a standard semver version tag is used
source = "../../"

scope = azurerm_resource_group.this.id

role_assignments = [
{
user_principal_names = ["[email protected]", "[email protected]"]
role_names = ["Contributor", "Reader"]
},
{
group_names = ["Group1"]
role_names = ["Reader"]
},
{
service_principal_names = ["test"]
role_names = ["Contributor"]
},
{
principal_ids = ["00000000-0000-0000-0000-000000000000"]
role_names = ["Reader"]
}
]
}
49 changes: 49 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
locals {
group_assignments = flatten([
for ra in var.role_assignments : [
for group_name in ra.group_names : [
for role_name in ra.role_names : {
principal_name = group_name
principal_type = "Group"
role_name = role_name
}
]
]
])

user_assignments = flatten([
for ra in var.role_assignments : [
for user_principal_name in ra.user_principal_names : [
for role_name in ra.role_names : {
principal_name = user_principal_name
principal_type = "User"
role_name = role_name
}
]
]
])

sp_assignments = flatten([
for ra in var.role_assignments : [
for sp_name in ra.service_principal_names : [
for role_name in ra.role_names : {
principal_name = sp_name
principal_type = "ServicePrincipal"
role_name = role_name
}
]
]
])

principal_id_assignments = flatten([
for ra in var.role_assignments : [
for principal_id in ra.principal_ids : [
for role_name in ra.role_names : {
principal_id = principal_id
principal_type = "ServicePrincipal"
role_name = role_name
}
]
]
])
}
Loading

0 comments on commit d5ebd87

Please sign in to comment.