Skip to content

Commit 86abae7

Browse files
committed
feat: add comments for replicator and metering module
1 parent bda5adf commit 86abae7

File tree

5 files changed

+222
-1
lines changed

5 files changed

+222
-1
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<!-- BEGIN_TF_DOCS -->
2+
## Requirements
3+
4+
| Name | Version |
5+
|------|---------|
6+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
7+
| <a name="requirement_azuread"></a> [azuread](#requirement\_azuread) | 2.18.0 |
8+
| <a name="requirement_azurerm"></a> [azurerm](#requirement\_azurerm) | 3.3.0 |
9+
10+
## Providers
11+
12+
| Name | Version |
13+
|------|---------|
14+
| <a name="provider_azuread"></a> [azuread](#provider\_azuread) | 2.18.0 |
15+
| <a name="provider_azurerm"></a> [azurerm](#provider\_azurerm) | 3.3.0 |
16+
17+
## Modules
18+
19+
No modules.
20+
21+
## Resources
22+
23+
| Name | Type |
24+
|------|------|
25+
| [azuread_application.meshcloud_metering](https://registry.terraform.io/providers/hashicorp/azuread/2.18.0/docs/resources/application) | resource |
26+
| [azuread_service_principal.meshcloud_metering](https://registry.terraform.io/providers/hashicorp/azuread/2.18.0/docs/resources/service_principal) | resource |
27+
| [azuread_service_principal_password.service_principal_pw](https://registry.terraform.io/providers/hashicorp/azuread/2.18.0/docs/resources/service_principal_password) | resource |
28+
| [azurerm_role_assignment.meshcloud_metering](https://registry.terraform.io/providers/hashicorp/azurerm/3.3.0/docs/resources/role_assignment) | resource |
29+
| [azurerm_role_assignment.meshcloud_metering_cloud_inventory](https://registry.terraform.io/providers/hashicorp/azurerm/3.3.0/docs/resources/role_assignment) | resource |
30+
| [azurerm_role_definition.meshcloud_metering_cloud_inventory_role](https://registry.terraform.io/providers/hashicorp/azurerm/3.3.0/docs/resources/role_definition) | resource |
31+
32+
## Inputs
33+
34+
| Name | Description | Type | Default | Required |
35+
|------|-------------|------|---------|:--------:|
36+
| <a name="input_scope"></a> [scope](#input\_scope) | The scope to which Service Principal permissions should be assigned to. Usually this is the management group id of form `/providers/Microsoft.Management/managementGroups/<tenantId>` that sits atop the subscriptions. | `string` | n/a | yes |
37+
| <a name="input_service_principal_name_suffix"></a> [service\_principal\_name\_suffix](#input\_service\_principal\_name\_suffix) | Service principal name suffix. | `string` | n/a | yes |
38+
39+
## Outputs
40+
41+
| Name | Description |
42+
|------|-------------|
43+
| <a name="output_service_principal"></a> [service\_principal](#output\_service\_principal) | Service Principal application id and object id |
44+
| <a name="output_service_principal_password"></a> [service\_principal\_password](#output\_service\_principal\_password) | Password for the Service Principal. |
45+
<!-- END_TF_DOCS -->
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
//---------------------------------------------------------------------------
2+
// Terraform Settings
3+
//---------------------------------------------------------------------------
4+
terraform {
5+
required_version = ">= 1.0"
6+
required_providers {
7+
azurerm = {
8+
source = "hashicorp/azurerm"
9+
version = "3.3.0"
10+
}
11+
azuread = {
12+
source = "hashicorp/azuread"
13+
version = "2.18.0"
14+
}
15+
}
16+
}
17+
18+
# At this point, we would have liked to use a custom role for the following reasons:
19+
# - permissions are explicitedly stated and can easily be fine tuned in the future
20+
# - we are independent of changes to Built-In Roles by Microsoft
21+
# - we could have restricted the existence of the role to just it's scope
22+
# HOWEVER, since Microsoft decided you cannot assign the 'Microsoft.Billing/billingPeriods/read' via the api (Status=400 Code="InvalidActionOrNotAction" Message="'Microsoft.Billing/billingPeriods/read' does not match any of the actions supported by the providers.")
23+
# we have to use a built in role for now that has that permission. If in the future they fix this problem, we can use the following custom role snippet
24+
# resource azurerm_role_definition meshcloud_metering {
25+
# name = "metering.${var.service_principal_name_suffix}"
26+
# scope = var.scope
27+
# description = "Permissions required by meshcloud in order to supply billing and usage data via its metering module"
28+
29+
# permissions {
30+
# actions = [
31+
# "Microsoft.Consumption/*/read",
32+
# "Microsoft.CostManagement/*/read",
33+
# "Microsoft.Billing/billingPeriods/read",
34+
# "Microsoft.Resources/subscriptions/read",
35+
# "Microsoft.Resources/subscriptions/resourceGroups/read",
36+
# "Microsoft.Support/*",
37+
# "Microsoft.Advisor/configurations/read",
38+
# "Microsoft.Advisor/recommendations/read",
39+
# "Microsoft.Management/managementGroups/read"
40+
# ]
41+
# }
42+
43+
# assignable_scopes = [
44+
# var.scope
45+
# ]
46+
# }
47+
48+
//---------------------------------------------------------------------------
49+
// Assign Cost Management reader role to the enterprise application
50+
//---------------------------------------------------------------------------
51+
# For now we are using the following built-in role
52+
resource "azurerm_role_assignment" "meshcloud_metering" {
53+
scope = var.scope
54+
role_definition_name = "Cost Management Reader"
55+
principal_id = azuread_service_principal.meshcloud_metering.id
56+
}
57+
58+
//---------------------------------------------------------------------------
59+
// Create custom role definition
60+
//---------------------------------------------------------------------------
61+
# If more resources are collected in the future, the permissions to read those should be added here.
62+
resource "azurerm_role_definition" "meshcloud_metering_cloud_inventory_role" {
63+
name = "metering.${var.service_principal_name_suffix}_cloud_inventory_role"
64+
scope = var.scope
65+
description = "Permissions required by meshcloud in order to collect information about resources in the metering module"
66+
67+
permissions {
68+
actions = [
69+
"Microsoft.Network/publicIPAddresses/read",
70+
"Microsoft.Network/networkInterfaces/read",
71+
"Microsoft.Compute/virtualMachines/*/read"
72+
]
73+
}
74+
75+
assignable_scopes = [
76+
var.scope
77+
]
78+
}
79+
80+
//---------------------------------------------------------------------------
81+
// Assign Custom role to the enterprise application
82+
//---------------------------------------------------------------------------
83+
resource "azurerm_role_assignment" "meshcloud_metering_cloud_inventory" {
84+
scope = var.scope
85+
role_definition_id = azurerm_role_definition.meshcloud_metering_cloud_inventory_role.role_definition_resource_id
86+
principal_id = azuread_service_principal.meshcloud_metering.id
87+
}
88+
89+
//---------------------------------------------------------------------------
90+
// Create New application in Microsoft Entra ID
91+
//---------------------------------------------------------------------------
92+
resource "azuread_application" "meshcloud_metering" {
93+
display_name = "metering.${var.service_principal_name_suffix}"
94+
95+
web {
96+
implicit_grant {
97+
access_token_issuance_enabled = false
98+
}
99+
}
100+
101+
}
102+
103+
//---------------------------------------------------------------------------
104+
// Create New Enterprise application and associate it with the previously created app
105+
//---------------------------------------------------------------------------
106+
resource "azuread_service_principal" "meshcloud_metering" {
107+
application_id = azuread_application.meshcloud_metering.application_id
108+
}
109+
110+
//---------------------------------------------------------------------------
111+
// Create a password for the Enterprise application
112+
//---------------------------------------------------------------------------
113+
resource "azuread_service_principal_password" "service_principal_pw" {
114+
service_principal_id = azuread_service_principal.meshcloud_metering.id
115+
end_date = "2999-01-01T01:02:03Z" # no expiry
116+
}
117+
118+
# facilitate migration from v0.1.0 of the module
119+
moved {
120+
from = azuread_service_principal_password.spp_pw
121+
to = azuread_service_principal_password.service_principal_pw
122+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
output "service_principal" {
2+
description = "Service Principal application id and object id"
3+
value = {
4+
object_id = azuread_service_principal.meshcloud_metering.id
5+
app_id = azuread_service_principal.meshcloud_metering.application_id
6+
password = "Execute `terraform output service_principal_password` to see the password"
7+
}
8+
}
9+
10+
output "service_principal_password" {
11+
description = "Password for the Service Principal."
12+
value = azuread_service_principal_password.service_principal_pw.value
13+
sensitive = true
14+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
variable "service_principal_name_suffix" {
2+
type = string
3+
description = "Service principal name suffix."
4+
}
5+
6+
variable "scope" {
7+
type = string
8+
description = "The scope to which Service Principal permissions should be assigned to. Usually this is the management group id of form `/providers/Microsoft.Management/managementGroups/<tenantId>` that sits atop the subscriptions."
9+
}

modules/meshcloud-replicator-service-principal/module.tf

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
1+
//---------------------------------------------------------------------------
2+
// Terraform Settings
3+
//---------------------------------------------------------------------------
24
terraform {
35
required_version = ">= 1.0"
46
required_providers {
@@ -13,6 +15,9 @@ terraform {
1315
}
1416
}
1517

18+
//---------------------------------------------------------------------------
19+
// Role Definition for the Replicator on the specified Scope
20+
//---------------------------------------------------------------------------
1621
resource "azurerm_role_definition" "meshcloud_replicator" {
1722
name = "replicator.${var.service_principal_name_suffix}"
1823
scope = var.scope
@@ -59,12 +64,20 @@ resource "azurerm_role_definition" "meshcloud_replicator" {
5964
]
6065
}
6166

67+
//---------------------------------------------------------------------------
68+
// Queries Entra ID for information about well-known application IDs.
69+
// Retrieve details about the service principal
70+
//---------------------------------------------------------------------------
71+
6272
data "azuread_application_published_app_ids" "well_known" {}
6373

6474
data "azuread_service_principal" "msgraph" {
6575
application_id = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph
6676
}
6777

78+
//---------------------------------------------------------------------------
79+
// Create New application in Microsoft Entra ID
80+
//---------------------------------------------------------------------------
6881
resource "azuread_application" "meshcloud_replicator" {
6982
display_name = "replicator.${var.service_principal_name_suffix}"
7083

@@ -119,6 +132,9 @@ resource "azuread_application" "meshcloud_replicator" {
119132
}
120133
}
121134

135+
//---------------------------------------------------------------------------
136+
// Create new Enterprise Application and associate it with the previous application
137+
//---------------------------------------------------------------------------
122138
resource "azuread_service_principal" "meshcloud_replicator" {
123139
application_id = azuread_application.meshcloud_replicator.application_id
124140
# The following tags are needed to create an Enterprise Application
@@ -128,12 +144,18 @@ resource "azuread_service_principal" "meshcloud_replicator" {
128144
]
129145
}
130146

147+
//---------------------------------------------------------------------------
148+
// Assign the created ARM role to the Enterprise application
149+
//---------------------------------------------------------------------------
131150
resource "azurerm_role_assignment" "meshcloud_replicator" {
132151
scope = var.scope
133152
role_definition_id = azurerm_role_definition.meshcloud_replicator.role_definition_resource_id
134153
principal_id = azuread_service_principal.meshcloud_replicator.id
135154
}
136155

156+
//---------------------------------------------------------------------------
157+
// Assign Entra ID Roles to the Enterprise application
158+
//---------------------------------------------------------------------------
137159
resource "azuread_app_role_assignment" "meshcloud_replicator-directory" {
138160
app_role_id = data.azuread_service_principal.msgraph.app_role_ids["Directory.Read.All"]
139161
principal_object_id = azuread_service_principal.meshcloud_replicator.object_id
@@ -152,11 +174,19 @@ resource "azuread_app_role_assignment" "meshcloud_replicator-user" {
152174
resource_object_id = data.azuread_service_principal.msgraph.object_id
153175
}
154176

177+
//---------------------------------------------------------------------------
178+
// Generate new password for the service principal
179+
//---------------------------------------------------------------------------
155180
resource "azuread_service_principal_password" "service_principal_pw" {
156181
service_principal_id = azuread_service_principal.meshcloud_replicator.id
157182
end_date = "2999-01-01T01:02:03Z" # no expiry
158183
}
159184

185+
186+
//---------------------------------------------------------------------------
187+
// Policy Definition for preventing the Application from assigning other privileges to itself
188+
// Assign it to the specified scope
189+
//---------------------------------------------------------------------------
160190
resource "azurerm_policy_definition" "privilege_escalation_prevention" {
161191
name = "meshcloud-privilege-escalation-prevention"
162192
policy_type = "Custom"
@@ -185,6 +215,7 @@ resource "azurerm_policy_definition" "privilege_escalation_prevention" {
185215
RULE
186216
}
187217

218+
188219
resource "azurerm_management_group_policy_assignment" "privilege-escalation-prevention" {
189220
name = "mesh-priv-escal-prev"
190221
policy_definition_id = azurerm_policy_definition.privilege_escalation_prevention.id

0 commit comments

Comments
 (0)