Skip to content

Commit acf102f

Browse files
committed
feat: initial azure tf modules
1 parent 575e88b commit acf102f

File tree

21 files changed

+602
-2
lines changed

21 files changed

+602
-2
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.terraform
2+
.terraform.lock.hcl

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
# terraform-azurerm-meshplatform
2-
Terraform module to integrate Azure as a meshPlatform
1+
# meshPlatform Azure Module
2+
3+
Terraform module to integrate Azure as a meshPlatform into meshStack instance.
4+

main.tf

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
terraform {
2+
required_version = ">= 0.13"
3+
required_providers {
4+
azurerm = {
5+
source = "hashicorp/azurerm"
6+
version = "2.12.0"
7+
}
8+
}
9+
# Set backend here
10+
}
11+
12+
provider "azurerm" {
13+
features {}
14+
}
15+
16+
data "azurerm_management_group" "root" {
17+
name = var.mgmt_group_id
18+
}
19+
20+
module "replicator_spp" {
21+
source = "./modules/meshcloud-replicator-spp/"
22+
23+
spp_name_suffix = var.spp_name_suffix
24+
scope = data.azurerm_management_group.root.id
25+
26+
additional_required_resource_accesses = []
27+
additional_permissions = []
28+
}
29+
30+
module "kraken_spp" {
31+
source = "./modules/meshcloud-kraken-spp/"
32+
33+
spp_name_suffix = var.spp_name_suffix
34+
scope = data.azurerm_management_group.root.id
35+
}
36+
37+
module "idp_lookup_spp" {
38+
source = "./modules/meshcloud-idp-lookup-spp/"
39+
40+
spp_name_suffix = var.spp_name_suffix
41+
scope = data.azurerm_management_group.root.id
42+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This modules creates an Azure Service Principal (Azure SPP) that is used by meshStack for User lookups in AAD IDP.
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
terraform {
2+
required_version = ">= 0.13"
3+
required_providers {
4+
azurerm = {
5+
source = "hashicorp/azurerm"
6+
version = "2.12.0"
7+
}
8+
random = {
9+
source = "hashicorp/random"
10+
version = "2.2.1"
11+
}
12+
azuread = {
13+
source = "hashicorp/azuread"
14+
version = "0.9.0"
15+
}
16+
}
17+
}
18+
19+
provider "azurerm" {
20+
features {}
21+
}
22+
23+
resource "azuread_application" "meshcloud_idp_lookup" {
24+
name = "idplookup.${var.spp_name_suffix}"
25+
26+
oauth2_allow_implicit_flow = false
27+
28+
required_resource_access {
29+
resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
30+
31+
# We only require this User.Read.All permission to see all of the Users in the AAD https://docs.microsoft.com/en-us/graph/permissions-reference#microsoft-graph-permission-names
32+
# Since this is a role (and not a scope) permission, you also have to enable admin consent in azure portal
33+
resource_access {
34+
id = "df021288-bdef-4463-88db-98f22de89214" # User.Read.All
35+
type = "Role"
36+
}
37+
38+
}
39+
40+
# NOTE: currently it is not possible to automate the "Grant admin consent button"
41+
# https://github.com/terraform-providers/terraform-provider-azuread/issues/33
42+
# As a result we have to ignore this value in terraform for now
43+
# In addition please keep in mind you have to grant admin consent manually
44+
lifecycle {
45+
ignore_changes = [
46+
app_role
47+
]
48+
}
49+
}
50+
51+
resource "azuread_service_principal" "meshcloud_idp_lookup" {
52+
application_id = azuread_application.meshcloud_idp_lookup.application_id
53+
}
54+
55+
resource "random_password" "spp_pw" {
56+
length = 64
57+
# Currently there are some passwords which do not allow you to login using az cli (see https://github.com/Azure/azure-cli/issues/12332)
58+
# Which is the reason we have set the flag to false
59+
special = false
60+
}
61+
62+
resource "azuread_service_principal_password" "spp_pw" {
63+
service_principal_id = azuread_service_principal.meshcloud_idp_lookup.id
64+
value = random_password.spp_pw.result
65+
end_date = "2999-01-01T01:02:03Z" # no expiry
66+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
output "service_principal" {
2+
value = {
3+
INFO = "On the very first time running tf apply, you have to run 'az ad app permission admin-consent --id ${azuread_service_principal.meshcloud_idp_lookup.application_id}' or click the 'Grant Admin consent button' in the portal"
4+
object_id = azuread_service_principal.meshcloud_idp_lookup.id
5+
app_id = azuread_service_principal.meshcloud_idp_lookup.application_id
6+
password = "Execute `terraform output idp_lookup_spp_password` to see the password"
7+
}
8+
}
9+
10+
output "service_principal_password" {
11+
description = "Password for the Service Principal."
12+
value = {
13+
password = random_password.spp_pw.result
14+
}
15+
sensitive = true
16+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
variable "spp_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 SPP permissions should be assigned to. Usually this is a management group that sits atop the subscriptions"
9+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This modules creates an Azure Service Principal (Azure SPP) that is used by meshStack to import metering data from Azure.
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
terraform {
2+
required_version = ">= 0.13"
3+
required_providers {
4+
azurerm = {
5+
source = "hashicorp/azurerm"
6+
version = "2.12.0"
7+
}
8+
random = {
9+
source = "hashicorp/random"
10+
version = "2.2.1"
11+
}
12+
azuread = {
13+
source = "hashicorp/azuread"
14+
version = "0.9.0"
15+
}
16+
}
17+
}
18+
19+
provider "azurerm" {
20+
features {}
21+
}
22+
23+
# At this point, we would have liked to use a custom role for the following reasons:
24+
# - permissions are explicitedly stated and can easily be fine tuned in the future
25+
# - we are independent of changes to Built-In Roles by Microsoft
26+
# - we could have restricted the existence of the role to just it's scope
27+
# 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.")
28+
# 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
29+
# resource azurerm_role_definition meshcloud_kraken {
30+
# name = "kraken.${var.spp_name_suffix}"
31+
# scope = var.scope
32+
# description = "Permissions required by meshcloud in order to supply billing and usage data via its kraken module"
33+
34+
# permissions {
35+
# actions = [
36+
# "Microsoft.Consumption/*/read",
37+
# "Microsoft.CostManagement/*/read",
38+
# "Microsoft.Billing/billingPeriods/read",
39+
# "Microsoft.Resources/subscriptions/read",
40+
# "Microsoft.Resources/subscriptions/resourceGroups/read",
41+
# "Microsoft.Support/*",
42+
# "Microsoft.Advisor/configurations/read",
43+
# "Microsoft.Advisor/recommendations/read",
44+
# "Microsoft.Management/managementGroups/read"
45+
# ]
46+
# }
47+
48+
# assignable_scopes = [
49+
# var.scope
50+
# ]
51+
# }
52+
53+
# For now we are using the following built-in role
54+
resource "azurerm_role_assignment" "meshcloud_kraken" {
55+
scope = var.scope
56+
role_definition_name = "Cost Management Reader"
57+
principal_id = azuread_service_principal.meshcloud_kraken.id
58+
}
59+
60+
# If more resources are collected in the future, the permissions to read those should be added here.
61+
resource "azurerm_role_definition" "meshcloud_kraken_cloud_inventory_role" {
62+
name = "kraken.${var.spp_name_suffix}_cloud_inventory_role"
63+
scope = var.scope
64+
description = "Permissions required by meshcloud in order to collect information about resources in the kraken module"
65+
66+
permissions {
67+
actions = [
68+
"Microsoft.Network/publicIPAddresses/read",
69+
"Microsoft.Network/networkInterfaces/read",
70+
"Microsoft.Compute/virtualMachines/*/read"
71+
]
72+
}
73+
74+
assignable_scopes = [
75+
var.scope
76+
]
77+
}
78+
79+
resource "azurerm_role_assignment" "meshcloud_kraken_cloud_inventory" {
80+
scope = var.scope
81+
role_definition_name = azurerm_role_definition.meshcloud_kraken_cloud_inventory_role.name
82+
principal_id = azuread_service_principal.meshcloud_kraken.id
83+
}
84+
85+
resource "azuread_application" "meshcloud_kraken" {
86+
name = "kraken.${var.spp_name_suffix}"
87+
oauth2_allow_implicit_flow = false
88+
}
89+
90+
resource "azuread_service_principal" "meshcloud_kraken" {
91+
application_id = azuread_application.meshcloud_kraken.application_id
92+
}
93+
94+
resource "random_password" "spp_pw" {
95+
length = 64
96+
# Currently there are some passwords which do not allow you to login using az cli (see https://github.com/Azure/azure-cli/issues/12332)
97+
# Which is the reason we have set the flag to false
98+
special = false
99+
}
100+
101+
resource "azuread_service_principal_password" "spp_pw" {
102+
service_principal_id = azuread_service_principal.meshcloud_kraken.id
103+
value = random_password.spp_pw.result
104+
end_date = "2999-01-01T01:02:03Z" # no expiry
105+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
output "service_principal" {
2+
value = {
3+
INFO = "On the very first time running tf apply, you have to run 'az ad app permission admin-consent --id ${azuread_service_principal.meshcloud_kraken.application_id}' or click the 'Grant Admin consent button' in the portal"
4+
object_id = azuread_service_principal.meshcloud_kraken.id
5+
app_id = azuread_service_principal.meshcloud_kraken.application_id
6+
password = "Execute `terraform output kraken_spp_password` to see the password"
7+
}
8+
}
9+
10+
output "service_principal_password" {
11+
description = "Password for the Service Principal."
12+
value = {
13+
password = random_password.spp_pw.result
14+
}
15+
sensitive = true
16+
}

0 commit comments

Comments
 (0)