[aad\_tenant\_id](#input\_aad\_tenant\_id) | Id of the AAD Tenant. This is also the simultaneously the id of the root management group. | `string` | n/a | yes |
| [documentation\_uami](#input\_documentation\_uami) | read-only UAMI with access to terraform states to generate documentation in CI pipelines | object({
name = string
# note: it seems wildcards are not supported yet, see https://github.com/Azure/azure-workload-identity/issues/373
oidc_subject = string
})
| `null` | no |
+| [key\_vault](#input\_key\_vault) | This object contains configuration details for setting up a key vault. | object({
name = string,
resource_group_name = string
})
| {
"name": "cloudfoundation-kv",
"resource_group_name": "cloudfoundation-rg"
}
| no |
| [parent\_management\_group\_name](#input\_parent\_management\_group\_name) | Name of the management group you want to use as parent for your foundation. | `string` | n/a | yes |
| [platform\_engineers\_group](#input\_platform\_engineers\_group) | the name of the cloud foundation platform engineers group | `string` | `"cloudfoundation-platform-engineers"` | no |
| [platform\_engineers\_members](#input\_platform\_engineers\_members) | Set up a group of platform engineers. If enabled, this group will receive access to terraform\_state\_storage | list(object({
email = string,
upn = string,
}))
| n/a | yes |
@@ -125,6 +132,8 @@ collie foundation deploy --bootstrap -- destroy
| Name | Description |
|------|-------------|
+| [azurerm\_key\_vault](#output\_azurerm\_key\_vault) | n/a |
+| [azurerm\_key\_vault\_rg\_name](#output\_azurerm\_key\_vault\_rg\_name) | n/a |
| [documentation\_md](#output\_documentation\_md) | n/a |
| [documentation\_uami\_client\_id](#output\_documentation\_uami\_client\_id) | n/a |
| [module\_storage\_account\_resource\_id](#output\_module\_storage\_account\_resource\_id) | n/a |
diff --git a/kit/azure/bootstrap/outputs.tf b/kit/azure/bootstrap/outputs.tf
index 31b49ba5..63ca9154 100644
--- a/kit/azure/bootstrap/outputs.tf
+++ b/kit/azure/bootstrap/outputs.tf
@@ -25,3 +25,11 @@ output "documentation_uami_client_id" {
output "validation_uami_client_id" {
value = length(azurerm_user_assigned_identity.validation) > 0 ? azurerm_user_assigned_identity.validation[0].client_id : null
}
+
+output "azurerm_key_vault" {
+ value = azurerm_key_vault.key_vault
+}
+
+output "azurerm_key_vault_rg_name" {
+ value = azurerm_resource_group.key_vault.name
+}
diff --git a/kit/azure/bootstrap/resources.key-vault.tf b/kit/azure/bootstrap/resources.key-vault.tf
new file mode 100644
index 00000000..eec50aba
--- /dev/null
+++ b/kit/azure/bootstrap/resources.key-vault.tf
@@ -0,0 +1,27 @@
+data "azurerm_client_config" "current" {}
+
+resource "azurerm_resource_group" "key_vault" {
+ name = var.key_vault.resource_group_name
+ location = var.terraform_state_storage.location
+}
+
+resource "azurerm_key_vault" "key_vault" {
+ name = var.key_vault.name
+ location = var.terraform_state_storage.location
+ resource_group_name = azurerm_resource_group.key_vault.name
+ tenant_id = data.azurerm_client_config.current.tenant_id
+ sku_name = "standard"
+ soft_delete_retention_days = 7
+ purge_protection_enabled = true
+ enable_rbac_authorization = true
+}
+
+data "azurerm_role_definition" "keyvault" {
+ name = "Key Vault Administrator"
+}
+
+resource "azurerm_role_assignment" "cloudfoundation_tfdeploy" {
+ principal_id = azuread_group.platform_engineers.id
+ scope = azurerm_key_vault.key_vault.id
+ role_definition_name = data.azurerm_role_definition.keyvault.name
+}
\ No newline at end of file
diff --git a/kit/azure/bootstrap/resources.validation-uami.tf b/kit/azure/bootstrap/resources.validation-uami.tf
index 6c63bee7..038369a2 100644
--- a/kit/azure/bootstrap/resources.validation-uami.tf
+++ b/kit/azure/bootstrap/resources.validation-uami.tf
@@ -61,9 +61,18 @@ resource "azuread_directory_role" "readers" {
display_name = "Directory Readers"
}
+# allow the validation user to read the cloudfoundation key vault
+resource "azurerm_role_assignment" "validation_reader_keyvault" {
+ count = var.validation_uami != null ? 1 : 0
+
+ principal_id = azurerm_user_assigned_identity.validation[0].principal_id
+ scope = azurerm_key_vault.key_vault.id
+ role_definition_name = data.azurerm_role_definition.keyvault.name
+}
+
resource "azuread_directory_role_assignment" "validation_reader" {
count = var.validation_uami != null ? 1 : 0
role_id = azuread_directory_role.readers.template_id
principal_object_id = azurerm_user_assigned_identity.validation[0].principal_id
-}
\ No newline at end of file
+}
diff --git a/kit/azure/bootstrap/template/platform-module/terragrunt.hcl b/kit/azure/bootstrap/template/platform-module/terragrunt.hcl
index 81f7676b..1a9fad0e 100644
--- a/kit/azure/bootstrap/template/platform-module/terragrunt.hcl
+++ b/kit/azure/bootstrap/template/platform-module/terragrunt.hcl
@@ -37,8 +37,8 @@ EOF
}
inputs = {
- aad_tenant_id = include.platform.locals.platform.azure.aadTenantId
- parent_management_group_name = "cloudfoundation-management-group" #TODO the cloudfoundation is created in a separate management group so as not to jeopardize the existing infrastructure
+ aad_tenant_id = include.platform.locals.platform.azure.aadTenantId
+
terraform_state_storage = {
name = "${include.platform.locals.cloudfoundation.name}"
location = "germanywestcentral" #TODO change, the azure location of the resource group and storage account
@@ -51,4 +51,10 @@ inputs = {
upn = "meshi@meshithesheep.onmicrosoft.com" #TODO change, enter PLATFORM ENGINEERS UPN here
}
]
+ key_vault = {
+ name = "likvid-cloudfoundation-kv"
+ resource_group_name = "likvid-cloudfoundation-keyvault"
+ }
+
+
}
diff --git a/kit/azure/bootstrap/terraform-state/version.tf b/kit/azure/bootstrap/terraform-state/version.tf
index ddb84ee3..7117131f 100644
--- a/kit/azure/bootstrap/terraform-state/version.tf
+++ b/kit/azure/bootstrap/terraform-state/version.tf
@@ -1,9 +1,3 @@
terraform {
required_version = ">= 1.0"
- required_providers {
- azurecaf = {
- source = "aztfmod/azurecaf"
- version = "~> 1.2.26"
- }
- }
}
diff --git a/kit/azure/bootstrap/variables.tf b/kit/azure/bootstrap/variables.tf
index a2da8400..0e233ffa 100644
--- a/kit/azure/bootstrap/variables.tf
+++ b/kit/azure/bootstrap/variables.tf
@@ -19,6 +19,20 @@ variable "terraform_state_storage" {
description = "Configure this object to enable setting up a terraform state store in Azure Storage."
}
+variable "key_vault" {
+ type = object({
+ name = string,
+ resource_group_name = string
+ })
+ nullable = false
+
+ description = "This object contains configuration details for setting up a key vault."
+ default = {
+ name = "cloudfoundation-kv"
+ resource_group_name = "cloudfoundation-rg"
+ }
+}
+
variable "platform_engineers_members" {
description = "Set up a group of platform engineers. If enabled, this group will receive access to terraform_state_storage"
type = list(object({
diff --git a/kit/azure/buildingblocks/automation/README.md b/kit/azure/buildingblocks/automation/README.md
index 274179b3..0524a61a 100644
--- a/kit/azure/buildingblocks/automation/README.md
+++ b/kit/azure/buildingblocks/automation/README.md
@@ -44,6 +44,7 @@ No modules.
| [azurerm_policy_definition.buildingblock_access](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/policy_definition) | resource |
| [azurerm_resource_group.tfstates](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) | resource |
| [azurerm_role_assignment.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
+| [azurerm_role_assignment.keyvault_administrator](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_assignment.tfstates_engineers](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
| [azurerm_role_definition.buildingblock_plan](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition) | resource |
| [azurerm_storage_account.tfstates](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account) | resource |
@@ -52,12 +53,15 @@ No modules.
| [time_rotating.key_rotation](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/rotating) | resource |
| [azuread_application_published_app_ids.well_known](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/application_published_app_ids) | data source |
| [azuread_service_principal.msgraph](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/data-sources/service_principal) | data source |
+| [azurerm_key_vault.cf_key_vault](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault) | data source |
+| [azurerm_role_definition.keyvault_administrator](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/role_definition) | data source |
| [azurerm_subscription.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source |
## Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
+| [key\_vault](#input\_key\_vault) | Key Vault configuration | object({
name = string
resource_group_name = string
})
| n/a | yes |
| [location](#input\_location) | Azure location for deploying the storage account | `string` | n/a | yes |
| [scope](#input\_scope) | n/a | `string` | n/a | yes |
| [service\_principal\_name](#input\_service\_principal\_name) | n/a | `string` | n/a | yes |
diff --git a/kit/azure/buildingblocks/automation/documentation.tf b/kit/azure/buildingblocks/automation/documentation.tf
index 417b99ae..ba090f71 100644
--- a/kit/azure/buildingblocks/automation/documentation.tf
+++ b/kit/azure/buildingblocks/automation/documentation.tf
@@ -1,5 +1,22 @@
output "documentation_md" {
value = <
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.0 |
+| [azurerm](#requirement\_azurerm) | ~> 3.71.0 |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [azurerm_role_assignment.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
+| [azurerm_role_definition.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition) | resource |
+| [azurerm_subscription.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [name](#input\_name) | name of the building block, used for naming resources | `string` | `"budget-alert"` | no |
+| [principal\_ids](#input\_principal\_ids) | set of principal ids that will be granted permissions to deploy the building block | `set(string)` | n/a | yes |
+| [scope](#input\_scope) | Scope where the building block should be deployable, typically the parent of all Landing Zones. | `string` | n/a | yes |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [documentation\_md](#output\_documentation\_md) | Markdown documentation with information about the Budget Alert building block backplane |
+| [role\_assignment\_ids](#output\_role\_assignment\_ids) | The IDs of the role assignments for the service principals. |
+| [role\_assignment\_principal\_ids](#output\_role\_assignment\_principal\_ids) | The principal IDs of the service principals that have been assigned the role. |
+| [role\_definition\_id](#output\_role\_definition\_id) | The ID of the role definition that enables deployment of the building block to subscriptions. |
+| [role\_definition\_name](#output\_role\_definition\_name) | The name of the role definition that enables deployment of the building block to subscriptions. |
+| [scope](#output\_scope) | The scope where the role definition and role assignments are applied. |
+
\ No newline at end of file
diff --git a/kit/azure/buildingblocks/budget-alert/backplane/documentation.tf b/kit/azure/buildingblocks/budget-alert/backplane/documentation.tf
new file mode 100644
index 00000000..f2802608
--- /dev/null
+++ b/kit/azure/buildingblocks/budget-alert/backplane/documentation.tf
@@ -0,0 +1,35 @@
+output "documentation_md" {
+ value = <
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.0 |
+| [azurerm](#requirement\_azurerm) | ~> 3.71.0 |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [azurerm_role_assignment.buildingblock_deploy_hub](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
+| [azurerm_role_definition.buildingblock_deploy_hub](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition) | resource |
+| [azurerm_subscription.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [name](#input\_name) | name of the building block, used for naming resources | `string` | n/a | yes |
+| [principal\_ids](#input\_principal\_ids) | set of principal ids that will be granted permissions to deploy the building block | `set(string)` | n/a | yes |
+| [scope](#input\_scope) | Scope where the building block should be deployable, typically the parent of all Landing Zones. | `string` | n/a | yes |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [documentation\_md](#output\_documentation\_md) | Markdown documentation with information about the Connectivity building block backplane |
+| [role\_assignment\_ids](#output\_role\_assignment\_ids) | The IDs of the role assignments for the service principals. |
+| [role\_assignment\_principal\_ids](#output\_role\_assignment\_principal\_ids) | The principal IDs of the service principals that have been assigned the role. |
+| [role\_definition\_id](#output\_role\_definition\_id) | The ID of the role definition that enables deployment of the Connectivity building block to the hub. |
+| [role\_definition\_name](#output\_role\_definition\_name) | The name of the role definition that enables deployment of the Connectivity building block to the hub. |
+| [scope](#output\_scope) | The scope where the role definition and role assignments are applied. |
+
\ No newline at end of file
diff --git a/kit/azure/buildingblocks/connectivity/backplane/documentation.tf b/kit/azure/buildingblocks/connectivity/backplane/documentation.tf
new file mode 100644
index 00000000..534d76ba
--- /dev/null
+++ b/kit/azure/buildingblocks/connectivity/backplane/documentation.tf
@@ -0,0 +1,32 @@
+output "documentation_md" {
+ value = < azurerm_role_assignment.buildingblock_deploy_hub[id].id }
+ description = "The IDs of the role assignments for the service principals."
+}
+
+output "role_assignment_principal_ids" {
+ value = { for id in var.principal_ids : id => azurerm_role_assignment.buildingblock_deploy_hub[id].principal_id }
+ description = "The principal IDs of the service principals that have been assigned the role."
+}
+
+output "scope" {
+ value = data.azurerm_subscription.current.id
+ description = "The scope where the role definition and role assignments are applied."
+}
+
diff --git a/kit/azure/buildingblocks/connectivity/backplane/template/platform-module/terragrunt.hcl b/kit/azure/buildingblocks/connectivity/backplane/template/platform-module/terragrunt.hcl
new file mode 100644
index 00000000..78b46943
--- /dev/null
+++ b/kit/azure/buildingblocks/connectivity/backplane/template/platform-module/terragrunt.hcl
@@ -0,0 +1,45 @@
+include "platform" {
+ path = find_in_parent_folders("platform.hcl")
+ expose = true
+}
+
+dependency "networking" {
+ config_path = "../../networking"
+}
+
+dependency "corp_online" {
+ config_path = "../../landingzones/corp-online"
+}
+
+dependency "automation" {
+ config_path = "../automation"
+}
+
+# deploy to the hub subscription
+generate "provider" {
+ path = "provider.tf"
+ if_exists = "overwrite"
+ contents = < Error: checking for presence of existing Virtual Network (Subscription: "b53caa89-ba38-4f04-a0b2-f989c98d4add"
+# > Resource Group Name: "connectivity"
+# > Virtual Network Name: "vnet-demo-app-vnet"): network.VirtualNetworksClient#Get: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="AuthorizationFailed" Message="The client 'dca119ef-092d-41ce-83d3-920d4eda271a' with object id 'dca119ef-092d-41ce-83d3-920d4eda271a' does not have authorization to perform action 'Microsoft.Network/virtualNetworks/read' over scope '/subscriptions/b53caa89-ba38-4f04-a0b2-f989c98d4add/resourceGroups/connectivity/providers/Microsoft.Network/virtualNetworks/vnet-demo-app-vnet' or the scope is invalid. If access was recently granted, please refresh your credentials."
+resource "time_sleep" "wait_for_spoke_rg_role" {
+ depends_on = [azurerm_role_assignment.spoke_rg]
+ create_duration = local.azure_delay
+}
+
#
# 3. deploy the actual network
#
resource "azurerm_virtual_network" "spoke_vnet" {
provider = azurerm.spoke
- depends_on = [azurerm_role_assignment.spoke_rg]
+ depends_on = [time_sleep.wait_for_spoke_rg_role]
name = "${var.name}-vnet"
location = azurerm_resource_group.spoke_rg.location
@@ -51,8 +67,15 @@ data "azurerm_virtual_network" "hub_vnet" {
resource_group_name = data.azurerm_resource_group.hub_rg.name
}
+# azure sometimes does not find the new spokle vnet for creating the peer, hence also giving this a delay
+resource "time_sleep" "wait_before_peering" {
+ depends_on = [azurerm_virtual_network.spoke_vnet]
+ create_duration = local.azure_delay
+}
+
resource "azurerm_virtual_network_peering" "spoke_hub_peer" {
- provider = azurerm.spoke
+ provider = azurerm.spoke
+ depends_on = [time_sleep.wait_before_peering]
name = var.name
resource_group_name = azurerm_resource_group.spoke_rg.name
@@ -61,7 +84,8 @@ resource "azurerm_virtual_network_peering" "spoke_hub_peer" {
}
resource "azurerm_virtual_network_peering" "hub_spoke_peer" {
- provider = azurerm.hub
+ provider = azurerm.hub
+ depends_on = [time_sleep.wait_before_peering]
name = var.name
resource_group_name = data.azurerm_resource_group.hub_rg.name
diff --git a/kit/azure/buildingblocks/connectivity/buildingblock/variables.tf b/kit/azure/buildingblocks/connectivity/buildingblock/variables.tf
index bcdaa361..7f45dd0e 100644
--- a/kit/azure/buildingblocks/connectivity/buildingblock/variables.tf
+++ b/kit/azure/buildingblocks/connectivity/buildingblock/variables.tf
@@ -24,3 +24,9 @@ variable "spoke_owner_principal_id" {
description = "Principal id that will become owner of the spokes. Defaults to the client_id of the spoke azurerm provider."
default = null
}
+
+variable "azure_delay_seconds" {
+ type = number
+ description = "Number of additional seconds to wait between Azure API operations to mitigate eventual consistency issues in order to increase automation reliabilty."
+ default = 30
+}
\ No newline at end of file
diff --git a/kit/azure/buildingblocks/connectivity/buildingblock/versions.tf b/kit/azure/buildingblocks/connectivity/buildingblock/versions.tf
index a8bcdf28..53fb53d9 100644
--- a/kit/azure/buildingblocks/connectivity/buildingblock/versions.tf
+++ b/kit/azure/buildingblocks/connectivity/buildingblock/versions.tf
@@ -5,8 +5,13 @@ terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
- version = ">=3.71.0"
+ version = "~> 3.106.1"
configuration_aliases = [azurerm.spoke, azurerm.hub]
}
+
+ time = {
+ source = "hashicorp/time"
+ version = "0.11.1"
+ }
}
}
diff --git a/kit/azure/buildingblocks/github-repo/backplane/documentation.tf b/kit/azure/buildingblocks/github-repo/backplane/documentation.tf
new file mode 100644
index 00000000..2f067e5b
--- /dev/null
+++ b/kit/azure/buildingblocks/github-repo/backplane/documentation.tf
@@ -0,0 +1,11 @@
+output "documentation_md" {
+ value = <
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [azurerm](#requirement\_azurerm) | ~> 3.81.0 |
+| [github](#requirement\_github) | 5.34.0 |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [github_repository.repository](https://registry.terraform.io/providers/integrations/github/5.34.0/docs/resources/repository) | resource |
+| [azurerm_key_vault.cloudfoundation_keyvault](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault) | data source |
+| [azurerm_key_vault_secret.github_token](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/key_vault_secret) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [create\_new](#input\_create\_new) | Flag to indicate whether to create a new repository | `bool` | n/a | yes |
+| [description](#input\_description) | Description of the GitHub repository | `string` | `"created by github-repo-building-block"` | no |
+| [github\_app\_id](#input\_github\_app\_id) | ID of the GitHub App | `string` | n/a | yes |
+| [github\_app\_installation\_id](#input\_github\_app\_installation\_id) | Installation ID of the GitHub App | `string` | n/a | yes |
+| [github\_org](#input\_github\_org) | Name of the GitHub organization | `string` | n/a | yes |
+| [github\_token\_secret\_name](#input\_github\_token\_secret\_name) | Name of the secret in Key Vault that holds the GitHub token | `string` | n/a | yes |
+| [key\_vault\_name](#input\_key\_vault\_name) | Name of the Key Vault | `string` | n/a | yes |
+| [key\_vault\_rg](#input\_key\_vault\_rg) | Name of the Resource Group where the Key Vault is located | `string` | n/a | yes |
+| [repo\_name](#input\_repo\_name) | Name of the GitHub repository | `string` | `"github-repo"` | no |
+| [template\_owner](#input\_template\_owner) | Owner of the template repository | `string` | `"template-owner"` | no |
+| [template\_repo](#input\_template\_repo) | Name of the template repository | `string` | `"github-repo"` | no |
+| [use\_template](#input\_use\_template) | Flag to indicate whether to create a repo based on a Template Repository | `bool` | `false` | no |
+| [visibility](#input\_visibility) | Visibility of the GitHub repository | `string` | `"private"` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [repo\_full\_name](#output\_repo\_full\_name) | n/a |
+| [repo\_git\_clone\_url](#output\_repo\_git\_clone\_url) | n/a |
+| [repo\_html\_url](#output\_repo\_html\_url) | n/a |
+| [repo\_name](#output\_repo\_name) | n/a |
+
diff --git a/kit/azure/buildingblocks/github-repo/buildingblock/icon.png b/kit/azure/buildingblocks/github-repo/buildingblock/icon.png
new file mode 100644
index 00000000..6cb3b705
Binary files /dev/null and b/kit/azure/buildingblocks/github-repo/buildingblock/icon.png differ
diff --git a/kit/azure/buildingblocks/github-repo/buildingblock/main.tf b/kit/azure/buildingblocks/github-repo/buildingblock/main.tf
new file mode 100644
index 00000000..9d996c33
--- /dev/null
+++ b/kit/azure/buildingblocks/github-repo/buildingblock/main.tf
@@ -0,0 +1,36 @@
+data "azurerm_key_vault" "cloudfoundation_keyvault" {
+ name = var.key_vault_name
+ resource_group_name = var.key_vault_rg
+}
+
+data "azurerm_key_vault_secret" "github_token" {
+ name = var.github_token_secret_name
+ key_vault_id = data.azurerm_key_vault.cloudfoundation_keyvault.id
+}
+
+provider "github" {
+ owner = var.github_org
+ app_auth {
+ id = var.github_app_id
+ installation_id = var.github_app_installation_id
+ pem_file = data.azurerm_key_vault_secret.github_token.value
+ }
+}
+
+resource "github_repository" "repository" {
+ count = var.create_new ? 1 : 0
+ name = var.repo_name
+ description = var.description
+ visibility = var.visibility
+ auto_init = false
+ vulnerability_alerts = true
+
+ dynamic "template" {
+ for_each = var.use_template ? [1] : []
+ content {
+ owner = var.template_owner
+ repository = var.template_repo
+ include_all_branches = true
+ }
+ }
+}
diff --git a/kit/azure/buildingblocks/github-repo/buildingblock/outputs.tf b/kit/azure/buildingblocks/github-repo/buildingblock/outputs.tf
new file mode 100644
index 00000000..ff075c93
--- /dev/null
+++ b/kit/azure/buildingblocks/github-repo/buildingblock/outputs.tf
@@ -0,0 +1,15 @@
+output "repo_name" {
+ value = var.create_new ? github_repository.repository[0].name : var.repo_name
+}
+
+output "repo_full_name" {
+ value = var.create_new ? github_repository.repository[0].full_name : "${var.github_org}/${var.repo_name}"
+}
+
+output "repo_html_url" {
+ value = var.create_new ? github_repository.repository[0].html_url : "https://github.com/${var.github_org}/${var.repo_name}"
+}
+
+output "repo_git_clone_url" {
+ value = var.create_new ? github_repository.repository[0].git_clone_url : "https://github.com/${var.github_org}/${var.repo_name}"
+}
diff --git a/kit/azure/buildingblocks/github-repo/buildingblock/provider.tf b/kit/azure/buildingblocks/github-repo/buildingblock/provider.tf
new file mode 100644
index 00000000..26c6cda5
--- /dev/null
+++ b/kit/azure/buildingblocks/github-repo/buildingblock/provider.tf
@@ -0,0 +1,12 @@
+terraform {
+ required_providers {
+ github = {
+ source = "integrations/github"
+ version = "5.34.0"
+ }
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = "~> 3.81.0"
+ }
+ }
+}
diff --git a/kit/azure/buildingblocks/github-repo/buildingblock/variables.tf b/kit/azure/buildingblocks/github-repo/buildingblock/variables.tf
new file mode 100644
index 00000000..8dc45d1f
--- /dev/null
+++ b/kit/azure/buildingblocks/github-repo/buildingblock/variables.tf
@@ -0,0 +1,73 @@
+variable "key_vault_name" {
+ type = string
+ description = "Name of the Key Vault"
+ sensitive = true
+}
+
+variable "key_vault_rg" {
+ type = string
+ description = "Name of the Resource Group where the Key Vault is located"
+ sensitive = true
+}
+
+variable "repo_name" {
+ type = string
+ default = "github-repo"
+ description = "Name of the GitHub repository"
+}
+
+variable "github_token_secret_name" {
+ type = string
+ description = "Name of the secret in Key Vault that holds the GitHub token"
+ sensitive = true
+}
+
+variable "github_org" {
+ type = string
+ description = "Name of the GitHub organization"
+}
+
+variable "create_new" {
+ type = bool
+ description = "Flag to indicate whether to create a new repository"
+}
+
+variable "description" {
+ type = string
+ default = "created by github-repo-building-block"
+ description = "Description of the GitHub repository"
+}
+
+variable "visibility" {
+ type = string
+ default = "private"
+ description = "Visibility of the GitHub repository"
+}
+
+variable "use_template" {
+ type = bool
+ description = "Flag to indicate whether to create a repo based on a Template Repository"
+ default = false
+}
+
+variable "template_owner" {
+ type = string
+ default = "template-owner"
+ description = "Owner of the template repository"
+}
+
+variable "template_repo" {
+ type = string
+ default = "github-repo"
+ description = "Name of the template repository"
+}
+
+variable "github_app_id" {
+ type = string
+ description = "ID of the GitHub App"
+}
+
+variable "github_app_installation_id" {
+ type = string
+ description = "Installation ID of the GitHub App"
+}
diff --git a/kit/azure/buildingblocks/subscription/backplane/README.md b/kit/azure/buildingblocks/subscription/backplane/README.md
new file mode 100644
index 00000000..ed970cd6
--- /dev/null
+++ b/kit/azure/buildingblocks/subscription/backplane/README.md
@@ -0,0 +1,54 @@
+---
+name: Azure Building Block - Subscription Baseline
+summary: |
+ Baseline for all subscriptions managed by the Likvid Bank Cloud Foundation Team.
+---
+
+# Azure Subscription Baseline
+
+This documentation is intended as a reference documentation for cloud foundation or platform engineers using this module.
+
+## Permissions
+
+This is a very simple building block backplane, which means it sets up permission to deploy the building block
+across all subscriptions underneath a management group (typically the top-level management group for landing zones).
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.0 |
+| [azurerm](#requirement\_azurerm) | ~> 3.71.0 |
+
+## Modules
+
+No modules.
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [azurerm_role_assignment.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) | resource |
+| [azurerm_role_definition.buildingblock_deploy](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_definition) | resource |
+| [azurerm_subscription.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/subscription) | data source |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [name](#input\_name) | name of the building block, used for naming resources | `string` | `"budget-alert"` | no |
+| [principal\_ids](#input\_principal\_ids) | set of principal ids that will be granted permissions to deploy the building block | `set(string)` | n/a | yes |
+| [scope](#input\_scope) | Scope where the building block should be deployable, typically the parent of all Landing Zones. | `string` | n/a | yes |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [documentation\_md](#output\_documentation\_md) | Markdown documentation with information about the Subscription building block backplane |
+| [role\_assignment\_ids](#output\_role\_assignment\_ids) | The IDs of the role assignments for the service principals. |
+| [role\_assignment\_principal\_ids](#output\_role\_assignment\_principal\_ids) | The principal IDs of the service principals that have been assigned the role. |
+| [role\_definition\_id](#output\_role\_definition\_id) | The ID of the role definition that enables deployment of the Subscription building block to subscriptions. |
+| [role\_definition\_name](#output\_role\_definition\_name) | The name of the role definition that enables deployment of the Subscription building block to subscriptions. |
+| [scope](#output\_scope) | The scope where the role definition and role assignments are applied. |
+
\ No newline at end of file
diff --git a/kit/azure/buildingblocks/subscription/backplane/documentation.tf b/kit/azure/buildingblocks/subscription/backplane/documentation.tf
new file mode 100644
index 00000000..aa67cbad
--- /dev/null
+++ b/kit/azure/buildingblocks/subscription/backplane/documentation.tf
@@ -0,0 +1,34 @@
+output "documentation_md" {
+ value = < azurerm_role_assignment.buildingblock_deploy[id].id }
+ description = "The IDs of the role assignments for the service principals."
+}
+
+output "role_assignment_principal_ids" {
+ value = { for id in var.principal_ids : id => azurerm_role_assignment.buildingblock_deploy[id].principal_id }
+ description = "The principal IDs of the service principals that have been assigned the role."
+}
+
+output "scope" {
+ value = var.scope
+ description = "The scope where the role definition and role assignments are applied."
+}
+
diff --git a/kit/azure/buildingblocks/subscription/backplane/variables.tf b/kit/azure/buildingblocks/subscription/backplane/variables.tf
new file mode 100644
index 00000000..ee7d43a2
--- /dev/null
+++ b/kit/azure/buildingblocks/subscription/backplane/variables.tf
@@ -0,0 +1,22 @@
+variable "name" {
+ type = string
+ nullable = false
+ default = "budget-alert"
+ description = "name of the building block, used for naming resources"
+ validation {
+ condition = can(regex("^[-a-z0-9]+$", var.name))
+ error_message = "Only alphanumeric lowercase characters and dashes are allowed"
+ }
+}
+
+variable "scope" {
+ type = string
+ nullable = false
+ description = "Scope where the building block should be deployable, typically the parent of all Landing Zones."
+}
+
+variable "principal_ids" {
+ type = set(string)
+ nullable = false
+ description = "set of principal ids that will be granted permissions to deploy the building block"
+}
\ No newline at end of file
diff --git a/kit/azure/buildingblocks/subscription/backplane/versions.tf b/kit/azure/buildingblocks/subscription/backplane/versions.tf
new file mode 100644
index 00000000..a0c42f5d
--- /dev/null
+++ b/kit/azure/buildingblocks/subscription/backplane/versions.tf
@@ -0,0 +1,10 @@
+terraform {
+ required_version = ">= 1.0"
+
+ required_providers {
+ azurerm = {
+ source = "hashicorp/azurerm"
+ version = "~> 3.71.0"
+ }
+ }
+}
diff --git a/kit/azure/landingzones/container-platform/README.md b/kit/azure/landingzones/container-platform/README.md
new file mode 100644
index 00000000..d1fe835d
--- /dev/null
+++ b/kit/azure/landingzones/container-platform/README.md
@@ -0,0 +1,51 @@
+---
+name: Azure Landing Zone "Container-Platform"
+summary: |
+ deploys new cloud foundation infrastructure.
+ Add a concise description of the module's purpose here.
+compliance:
+- control: cfmm/tenant-management/container-platform-landing-zone
+ statement: |
+ Restricts the list of permitted Azure services in relation to container Container-Platform.
+---
+
+# Azure Landing Zone "Container-Platform"
+
+The Container Platform Landing Zone is a pre-configured environment designed to support the deployment and management of containerized applications at scale. It provides a foundation for running container workloads using services like Azure Kubernetes Service (AKS) and Azure Container Instances (ACI).
+
+
+## Requirements
+
+| Name | Version |
+|------|---------|
+| [terraform](#requirement\_terraform) | >= 1.0 |
+| [azurerm](#requirement\_azurerm) | ~> 3.102.0 |
+
+## Modules
+
+| Name | Source | Version |
+|------|--------|---------|
+| [policy\_container\_platform](#module\_policy\_container\_platform) | github.com/meshcloud/collie-hub//kit/azure/util/azure-policies | 7c356a7 |
+
+## Resources
+
+| Name | Type |
+|------|------|
+| [azurerm_management_group.container_platform](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/management_group) | resource |
+
+## Inputs
+
+| Name | Description | Type | Default | Required |
+|------|-------------|------|---------|:--------:|
+| [landingzones](#input\_landingzones) | The parent\_management\_group where your landingzones are | `string` | `"landingzones"` | no |
+| [location](#input\_location) | The Azure location where this policy assignment should exist, required when an Identity is assigned. | `string` | `"germanywestcentral"` | no |
+| [lz-container-platform](#input\_lz-container-platform) | n/a | `string` | `"container-platform"` | no |
+| [parent\_management\_group\_id](#input\_parent\_management\_group\_id) | The tenant management group of your cloud foundation | `string` | `"foundation"` | no |
+
+## Outputs
+
+| Name | Description |
+|------|-------------|
+| [documentation\_md](#output\_documentation\_md) | n/a |
+| [management\_id](#output\_management\_id) | n/a |
+
diff --git a/kit/azure/landingzones/container-platform/documentation.tf b/kit/azure/landingzones/container-platform/documentation.tf
new file mode 100644
index 00000000..e89edd62
--- /dev/null
+++ b/kit/azure/landingzones/container-platform/documentation.tf
@@ -0,0 +1,18 @@
+output "documentation_md" {
+ value = < [location](#input\_location) | The Azure location where this policy assignment should exist, required when an Identity is assigned. | `string` | `"germanywestcentral"` | no |
| [online](#input\_online) | n/a | `string` | `"online"` | no |
| [parent\_management\_group\_id](#input\_parent\_management\_group\_id) | The tenant management group of your cloud foundation | `string` | `"lv-foundation"` | no |
+| [vnet\_address\_space\_id](#input\_vnet\_address\_space\_id) | The address space of the hub vnet for the policy assignment | `string` | n/a | yes |
## Outputs
diff --git a/kit/azure/landingzones/corp-online/documentation.tf b/kit/azure/landingzones/corp-online/documentation.tf
index 24d46cce..0cb90463 100644
--- a/kit/azure/landingzones/corp-online/documentation.tf
+++ b/kit/azure/landingzones/corp-online/documentation.tf
@@ -12,16 +12,14 @@ Landing zones for application teams are placed under either
### Active Policies Corp
-#### Service and Location Restrictions
-#### Centralized Audit Logs
-
|Policy|Effect|Description|Rationale|
|-|-|-|-|
-|[${module.policy_corp.policy_assignments["Audit-PeDnsZones"].display_name}](https://cloudfoundation.org/maturity-model/security-and-compliance/centralized-audit-logs.html#proven-patterns-when-implementing-centralized-audit-logs)|Audit|${module.policy_corp.policy_assignments["Audit-PeDnsZones"].description}|This policy helps to ensure that Private Link Private DNS Zone resources are deployed correctly and securely. By auditing the deployment of these resources, we can identify any potential issues or vulnerabilities and take corrective action to mitigate them.|
-|[${module.policy_corp.policy_assignments["Deploy-Private-DNS-Zones"].display_name}](https://https://cloudfoundation.org/maturity-model/security-and-compliance/service-and-location-restrictions.html#proven-patterns-for-implementing-cloud-resource-policies)|Deploy| ${module.policy_corp.policy_assignments["Deploy-Private-DNS-Zones"].description} |This policy helps to ensure that Azure PaaS services are integrated with Azure Private DNS zones, which provides a reliable, secure DNS service to manage and resolve domain names in a virtual network without the need to add a custom DNS solution.|
-|[${module.policy_corp.policy_assignments["Deny-HybridNetworking"].display_name}](https://https://cloudfoundation.org/maturity-model/security-and-compliance/service-and-location-restrictions.html#proven-patterns-for-implementing-cloud-resource-policies)|Deny|${module.policy_corp.policy_assignments["Deny-HybridNetworking"].description}|By denying these resources, we can ensure that all traffic to and from the resource is routed through the private network, which is more secure.|
-|[${module.policy_corp.policy_assignments["Deny-Public-Endpoints"].display_name}](https://https://cloudfoundation.org/maturity-model/security-and-compliance/service-and-location-restrictions.html#proven-patterns-for-implementing-cloud-resource-policies)|Deny|${module.policy_corp.policy_assignments["Deny-Public-Endpoints"].description} | By disabling public network access, we can ensure that all traffic to and from the resource is routed through the private network, which is more secure.|
-|[${module.policy_corp.policy_assignments["Deny-Public-IP-On-NIC"].display_name}](https://https://cloudfoundation.org/maturity-model/security-and-compliance/service-and-location-restrictions.html#proven-patterns-for-implementing-cloud-resource-policies)|Deny|${module.policy_corp.policy_assignments["Deny-Public-IP-On-NIC"].description}|By denying public IP addresses, we can ensure that all traffic to and from the resource is routed through the private network, which is more secure.|
+|[${module.policy_corp.policy_assignments["Audit-PeDnsZones"].display_name}](https://www.azadvertizer.net/azpolicyadvertizer/Audit-PrivateLinkDnsZones.html)|Audit|${module.policy_corp.policy_assignments["Audit-PeDnsZones"].description}|This policy helps to ensure that Private Link Private DNS Zone resources are deployed correctly and securely. By auditing the deployment of these resources, we can identify any potential issues or vulnerabilities and take corrective action to mitigate them.|
+|[${module.policy_corp.policy_assignments["Deploy-Private-DNS-Zones"].display_name}](https://www.azadvertizer.net/azpolicyadvertizer/Deny-Private-DNS-Zones.html)|Deploy| ${module.policy_corp.policy_assignments["Deploy-Private-DNS-Zones"].description} |This policy helps to ensure that Azure PaaS services are integrated with Azure Private DNS zones, which provides a reliable, secure DNS service to manage and resolve domain names in a virtual network without the need to add a custom DNS solution.|
+|[${module.policy_corp.policy_assignments["Deny-HybridNetworking"].display_name}](https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Policies)|Deny|${module.policy_corp.policy_assignments["Deny-HybridNetworking"].description}|By denying these resources, we can ensure that all traffic to and from the resource is routed through the private network, which is more secure.|
+|[${module.policy_corp.policy_assignments["Deny-Public-Endpoints"].display_name}]https://www.azadvertizer.net/azpolicyinitiativesadvertizer/Deny-PublicPaaSEndpoints.html)|Deny|${module.policy_corp.policy_assignments["Deny-Public-Endpoints"].description} | By disabling public network access, we can ensure that all traffic to and from the resource is routed through the private network, which is more secure.|
+|[${module.policy_corp.policy_assignments["Deny-Public-IP-On-NIC"].display_name}](https://www.azadvertizer.net/azpolicyadvertizer/83a86a26-fd1f-447c-b59d-e51f44264114.html)|Deny|${module.policy_corp.policy_assignments["Deny-Public-IP-On-NIC"].description}|By denying public IP addresses, we can ensure that all traffic to and from the resource is routed through the private network, which is more secure.|
+|[${module.policy_corp.policy_assignments["Deny-Peer-To-Non-A-VNET"].display_name}](https://www.azadvertizer.net/azpolicyadvertizer/Deny-VNET-Peering-To-Non-Approved-VNETs.html)|Deny|${module.policy_corp.policy_assignments["Deny-Peer-To-Non-A-VNET"].description}|By denying VNET peering to non-approved VNETs, we can ensure that all traffic to and from the resource is routed through the private network, which is more secure. This is a cosutmized version of the Enterprise-Scale policy|
### Active Policies Online
diff --git a/kit/azure/landingzones/corp-online/lib/corp/policy_assignments/policy_assignment_es_audit_network_changes.tmpl.json b/kit/azure/landingzones/corp-online/lib/corp/policy_assignments/policy_assignment_es_audit_network_changes.tmpl.json
new file mode 100644
index 00000000..e2538689
--- /dev/null
+++ b/kit/azure/landingzones/corp-online/lib/corp/policy_assignments/policy_assignment_es_audit_network_changes.tmpl.json
@@ -0,0 +1,18 @@
+{
+ "name": "Audit-Network-Changes",
+ "type": "Microsoft.Authorization/policyAssignments",
+ "location": "${default_location}",
+ "apiVersion": "2021-06-01",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+
+ "properties": {
+ "displayName": "Audit Network Changes Assignment",
+ "policyDefinitionId": "${root_scope_resource_id}/providers/Microsoft.Authorization/policyDefinitions/Audit-Network-Changes",
+ "scope": "${current_scope_resource_id}",
+
+ "parameters": {}
+ }
+}
+
diff --git a/kit/azure/landingzones/corp-online/lib/corp/policy_assignments/policy_assignment_es_deny_peering_to_non_approved.tmpl.json b/kit/azure/landingzones/corp-online/lib/corp/policy_assignments/policy_assignment_es_deny_peering_to_non_approved.tmpl.json
new file mode 100644
index 00000000..f0109357
--- /dev/null
+++ b/kit/azure/landingzones/corp-online/lib/corp/policy_assignments/policy_assignment_es_deny_peering_to_non_approved.tmpl.json
@@ -0,0 +1,25 @@
+{
+ "name": "Deny-Peer-To-Non-A-VNET",
+ "type": "Microsoft.Authorization/policyAssignments",
+ "location": "${default_location}",
+ "identity": {
+ "type": "SystemAssigned"
+ },
+ "apiVersion": "2021-06-01",
+ "properties": {
+ "displayName": "Deny VNET Peering To Non-Approved VNETs",
+ "policyDefinitionId": "${root_scope_resource_id}/providers/Microsoft.Authorization/policyDefinitions/Deny-VNET-Peering-To-Non-Approved-VNETs",
+ "scope": "${current_scope_resource_id}",
+ "notScopes": [],
+ "parameters": {
+ "effect": {
+ "value": "Deny"
+ },
+ "allowedVnets": {
+ "value": [
+ "${vnet_address_space_id}"
+ ]
+ }
+ }
+ }
+}
diff --git a/kit/azure/landingzones/corp-online/lib/corp/policy_definitions/policy_definition_es_audit_network_changes.json b/kit/azure/landingzones/corp-online/lib/corp/policy_definitions/policy_definition_es_audit_network_changes.json
new file mode 100644
index 00000000..972bfd37
--- /dev/null
+++ b/kit/azure/landingzones/corp-online/lib/corp/policy_definitions/policy_definition_es_audit_network_changes.json
@@ -0,0 +1,29 @@
+{
+ "name": "Audit-Network-Changes",
+ "type": "Microsoft.Authorization/policyDefinitions",
+ "apiVersion": "2021-06-01",
+ "properties": {
+ "displayName": "Audit Network Changes",
+ "description": "This policy audits all changes to network resources in Azure.",
+ "policyType": "Custom",
+ "mode": "All",
+ "metadata": {
+ "version": "1.0.0",
+ "category": "Network"
+ },
+ "parameters": {},
+ "policyRule": {
+ "if": {
+ "anyOf": [
+ {
+ "field": "type",
+ "like": "Microsoft.Network/*"
+ }
+ ]
+ },
+ "then": {
+ "effect": "audit"
+ }
+ }
+ }
+}
diff --git a/kit/azure/landingzones/corp-online/lib/corp/policy_definitions/policy_definition_es_deny_vnet_peering_to_non_approved_vnets.json b/kit/azure/landingzones/corp-online/lib/corp/policy_definitions/policy_definition_es_deny_vnet_peering_to_non_approved_vnets.json
new file mode 100644
index 00000000..3ca217a1
--- /dev/null
+++ b/kit/azure/landingzones/corp-online/lib/corp/policy_definitions/policy_definition_es_deny_vnet_peering_to_non_approved_vnets.json
@@ -0,0 +1,68 @@
+{
+ "name": "Deny-VNET-Peering-To-Non-Approved-VNETs",
+ "type": "Microsoft.Authorization/policyDefinitions",
+ "apiVersion": "2021-06-01",
+ "scope": null,
+ "properties": {
+ "policyType": "Custom",
+ "mode": "All",
+ "displayName": "Deny vNet peering to non-approved vNets",
+ "description": "This policy denies the creation of vNet Peerings to non-approved vNets under the assigned scope.",
+ "metadata": {
+ "version": "1.0.0",
+ "category": "Network",
+ "source": "https://github.com/Azure/Enterprise-Scale/",
+ "alzCloudEnvironments": [
+ "AzureCloud",
+ "AzureChinaCloud",
+ "AzureUSGovernment"
+ ]
+ },
+ "parameters": {
+ "effect": {
+ "type": "String",
+ "metadata": {
+ "displayName": "Effect",
+ "description": "Enable or disable the execution of the policy"
+ },
+ "allowedValues": [
+ "Audit",
+ "Deny",
+ "Disabled"
+ ],
+ "defaultValue": "Deny"
+ },
+ "allowedVnets": {
+ "type": "Array",
+ "metadata": {
+ "displayName": "Allowed vNets to peer with",
+ "description": "Array of allowed vNets that can be peered with. Must be entered using their resource ID. Example: /subscriptions/{subId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworks/{vnetName}"
+ },
+ "defaultValue": []
+ }
+ },
+ "policyRule": {
+ "if": {
+ "anyOf": [
+ {
+ "allOf": [
+ {
+ "field": "type",
+ "equals": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings"
+ },
+ {
+ "not": {
+ "field": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings/remoteVirtualNetwork.id",
+ "in": "[parameters('allowedVnets')]"
+ }
+ }
+ ]
+ }
+ ]
+ },
+ "then": {
+ "effect": "[parameters('effect')]"
+ }
+ }
+ }
+}
diff --git a/kit/azure/landingzones/corp-online/main.tf b/kit/azure/landingzones/corp-online/main.tf
index 3a81cd12..88a024d3 100644
--- a/kit/azure/landingzones/corp-online/main.tf
+++ b/kit/azure/landingzones/corp-online/main.tf
@@ -21,6 +21,7 @@ module "policy_corp" {
connectivity_location = "${var.location}"
current_scope_resource_id = azurerm_management_group.corp.id
root_scope_resource_id = azurerm_management_group.corp.id
+ vnet_address_space_id = var.vnet_address_space_id
private_dns_zone_prefix = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/${var.cloudfoundation}/dns/providers/Microsoft.Network/privateDnsZones/"
}
}
diff --git a/kit/azure/landingzones/corp-online/variables.tf b/kit/azure/landingzones/corp-online/variables.tf
index e0cf7a20..00f2e63a 100644
--- a/kit/azure/landingzones/corp-online/variables.tf
+++ b/kit/azure/landingzones/corp-online/variables.tf
@@ -27,3 +27,8 @@ variable "location" {
description = "The Azure location where this policy assignment should exist, required when an Identity is assigned."
default = "germanywestcentral"
}
+
+variable "vnet_address_space_id" {
+ type = string
+ description = "The address space of the hub vnet for the policy assignment"
+}
diff --git a/kit/azure/landingzones/sandbox/variables.tf b/kit/azure/landingzones/sandbox/variables.tf
index 77da2c91..9fa7ec79 100644
--- a/kit/azure/landingzones/sandbox/variables.tf
+++ b/kit/azure/landingzones/sandbox/variables.tf
@@ -7,7 +7,6 @@ variable "name" {
default = "sandbox"
}
-
variable "location" {
type = string
description = "The Azure location used for creating policy assignments establishing this landing zone's guardrails."
diff --git a/kit/azure/landingzones/serverless/lib/policy_assignments/policy_assignment_collie_allow_only_serverless_resources.tmpl.json b/kit/azure/landingzones/serverless/lib/policy_assignments/policy_assignment_collie_allow_only_serverless_resources.tmpl.json
index 51b9bc32..3c5d4ef0 100644
--- a/kit/azure/landingzones/serverless/lib/policy_assignments/policy_assignment_collie_allow_only_serverless_resources.tmpl.json
+++ b/kit/azure/landingzones/serverless/lib/policy_assignments/policy_assignment_collie_allow_only_serverless_resources.tmpl.json
@@ -6,7 +6,7 @@
"properties": {
"description": "This policy assignment allows only the deployment of serverless resources.",
"displayName": "Allow Serverless Resources Only",
- "policyDefinitionId": "${root_scope_resource_id}/providers/Microsoft.Authorization/policyDefinitions/Allow-OnlyServerlessResources",
+ "policyDefinitionId": "${current_scope_resource_id}/providers/Microsoft.Authorization/policyDefinitions/Allow-OnlyServerlessResources",
"enforcementMode": "Default",
"nonComplianceMessages": [
{
diff --git a/kit/azure/meshplatform/README.md b/kit/azure/meshplatform/README.md
index e4b17046..7be47a7f 100644
--- a/kit/azure/meshplatform/README.md
+++ b/kit/azure/meshplatform/README.md
@@ -19,7 +19,7 @@ No requirements.
| Name | Source | Version |
|------|--------|---------|
-| [meshplatform](#module\_meshplatform) | registry.terraform.io/meshcloud/meshplatform/azure | 0.5.0 |
+| [meshplatform](#module\_meshplatform) | registry.terraform.io/meshcloud/meshplatform/azure | 0.6.0 |
## Resources
@@ -31,6 +31,7 @@ No resources.
|------|-------------|------|---------|:--------:|
| [additional\_permissions](#input\_additional\_permissions) | Additional Subscription-Level Permissions the Service Principal needs. | `list(string)` | `[]` | no |
| [additional\_required\_resource\_accesses](#input\_additional\_required\_resource\_accesses) | Additional AAD-Level Resource Accesses the replicator Service Principal needs. | `list(object({ resource_app_id = string, resource_accesses = list(object({ id = string, type = string })) }))` | `[]` | no |
+| [can\_cancel\_subscriptions\_in\_scopes](#input\_can\_cancel\_subscriptions\_in\_scopes) | The scopes to which Service Principal cancel subscription permission is assigned to. List of management group id of form `/providers/Microsoft.Management/managementGroups//`. | `list(string)` | `[]` | no |
| [create\_passwords](#input\_create\_passwords) | Create passwords for service principals. | `bool` | `true` | no |
| [metering\_assignment\_scopes](#input\_metering\_assignment\_scopes) | Names or UUIDs of the Management Groups that kraken should collect costs for. | `list(string)` | n/a | yes |
| [metering\_enabled](#input\_metering\_enabled) | Whether to create Metering Service Principal or not. | `bool` | `true` | no |
diff --git a/kit/azure/meshplatform/main.tf b/kit/azure/meshplatform/main.tf
index f7e5975c..f083d869 100644
--- a/kit/azure/meshplatform/main.tf
+++ b/kit/azure/meshplatform/main.tf
@@ -4,7 +4,7 @@
module "meshplatform" {
source = "registry.terraform.io/meshcloud/meshplatform/azure"
- version = "0.5.0"
+ version = "0.6.0"
metering_enabled = var.metering_enabled
metering_service_principal_name = var.metering_service_principal_name
@@ -19,4 +19,5 @@ module "meshplatform" {
additional_required_resource_accesses = var.additional_required_resource_accesses
create_passwords = var.create_passwords
workload_identity_federation = var.workload_identity_federation
+ can_cancel_subscriptions_in_scopes = var.can_cancel_subscriptions_in_scopes
}
diff --git a/kit/azure/meshplatform/template/platform-module/terragrunt.hcl b/kit/azure/meshplatform/template/platform-module/terragrunt.hcl
new file mode 100644
index 00000000..3d11aae8
--- /dev/null
+++ b/kit/azure/meshplatform/template/platform-module/terragrunt.hcl
@@ -0,0 +1,38 @@
+include "platform" {
+ path = find_in_parent_folders("platform.hcl")
+ expose = true
+}
+
+dependency "bootstrap" {
+ config_path = "../bootstrap"
+}
+
+dependency "organization_hierarchy" {
+ config_path = "../organization-hierarchy"
+}
+
+generate "provider" {
+ path = "provider.tf"
+ if_exists = "overwrite"
+ contents = < [hub\_rg](#output\_hub\_rg) | Hub Resource Group name |
| [hub\_subscription](#output\_hub\_subscription) | Subscription of hub vnet |
| [hub\_vnet](#output\_hub\_vnet) | Hub VNet name |
+| [hub\_vnet\_id](#output\_hub\_vnet\_id) | Hub VNet id |
| [network\_admins\_azuread\_group\_id](#output\_network\_admins\_azuread\_group\_id) | n/a |
diff --git a/kit/azure/networking/outputs.tf b/kit/azure/networking/outputs.tf
index e8a4ee0a..a7660b6f 100644
--- a/kit/azure/networking/outputs.tf
+++ b/kit/azure/networking/outputs.tf
@@ -18,6 +18,11 @@ output "hub_vnet" {
description = "Hub VNet name"
}
+output "hub_vnet_id" {
+ value = azurerm_virtual_network.hub_network.id
+ description = "Hub VNet id"
+}
+
output "firewall_name" {
value = join("", azurerm_firewall.fw.*.name)
description = "Hub VNet firewall name"
diff --git a/kit/azure/organization-hierarchy/template/platform-module/terragrunt.hcl b/kit/azure/organization-hierarchy/template/platform-module/terragrunt.hcl
index 2158e99c..0118ecc9 100644
--- a/kit/azure/organization-hierarchy/template/platform-module/terragrunt.hcl
+++ b/kit/azure/organization-hierarchy/template/platform-module/terragrunt.hcl
@@ -30,7 +30,7 @@ locals {
inputs = {
# todo: set input variables
- parent_management_group_name = dependency.bootstrap.outputs.parent_management_group
+ parent_management_group_name = "${local.management_group_prefix}-foundation"
locations = ["germanywestcentral"]
management = "${local.management_group_prefix}-management"