-
Notifications
You must be signed in to change notification settings - Fork 568
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20 from krowlandson/main
Update for release 0.0.7-preview
- Loading branch information
Showing
4 changed files
with
150 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,42 +9,22 @@ This module provides an opinionated approach for delivering the core platform ca | |
Specifically, this module provides a consistent approach for deploying the following core platform components: | ||
|
||
- Management Group and Subscription organisation | ||
- Create the Management Group hierarchy | ||
- Create the Management Group resource hierarchy | ||
- Assign Subscriptions to Management Groups | ||
- Create custom Policy Definitions, Policy Set Definitions (Initiatives), and Policy Assignments (Enterprise-scale policies and customer-defined policies) | ||
- Create custom Policy Assignments, Policy Definitions and Policy Set Definitions (Initiatives)<br>(Enterprise-scale policies and customer-defined policies) | ||
- Identity and access management | ||
- Create custom Role Definitions, and Role Assignments (Enterprise-scale policies and customer-defined roles) | ||
- Create custom Role Assignments and Role Definitions<br>(Enterprise-scale roles and customer-defined roles) | ||
|
||
The following resource types are deployed and managed by this module: | ||
|
||
| Azure Resource | Terraform Resource | | ||
| -------------- | ------------------ | | ||
| [Management Groups][arm_management_group] | [`azurerm_management_group`][azurerm_management_group] | | ||
| [Policy Assignments][arm_policy_assignment] | [`azurerm_policy_assignment`][azurerm_policy_assignment] | | ||
| [Policy Definitions][arm_policy_definition] | [`azurerm_policy_definition`][azurerm_policy_definition] | | ||
| [Policy Set Definitions][arm_policy_set_definition] | [`azurerm_policy_set_definition`][azurerm_policy_set_definition] | | ||
| [Role Assignments][arm_role_assignment] | [`azurerm_role_assignment`][azurerm_role_assignment] | | ||
| [Role Definitions][arm_role_definition] | [`azurerm_role_definition`][azurerm_role_definition] | | ||
|
||
The concept of ***archetypes*** is used to define configuration settings for each ***Management Group*** using a template-driven approach. This approach is designed to make reading the high-level configuration settings easier, simplify the process of managing configuration and versioning, reduce code duplication (DRY), and to improve consistency in complex environments. An archetype is defined using a simple JSON structure (as below) and should define which policy and role settings should be deployed. This is associated to the scope (i.e. Management Group) as part of the ***Landing Zone*** definitions and is what fundamentally transforms ***Management Groups*** into ***Landing Zones***. | ||
|
||
**Example archetype definition structure** | ||
```json | ||
{ | ||
"archetype_id": { | ||
"policy_assignments": [], | ||
"policy_definitions": [], | ||
"policy_set_definitions": [], | ||
"role_definitions": [], | ||
"archetype_config": { | ||
"parameters": {}, | ||
"access_control": {} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
The module contains a default library of templates for the official Enterprise-scale Archetype Definitions, Policy Assignments, Policy Definitions, Policy Set Definitions, Role Assignments, and Role Definitions. These can be overridden using a custom library, details of which are provided under the usage section of this README (below). | ||
| | Azure Resource | Terraform Resource | | ||
| --- | -------------- | ------------------ | | ||
| Management Groups | [`Microsoft.Management/managementGroups`][arm_management_group] | [`azurerm_management_group`][azurerm_management_group] | | ||
| Policy Assignments | [`Microsoft.Authorization/policyAssignments`][arm_policy_assignment] | [`azurerm_policy_assignment`][azurerm_policy_assignment] | | ||
| Policy Definitions | [`Microsoft.Authorization/policyDefinitions`][arm_policy_definition] | [`azurerm_policy_definition`][azurerm_policy_definition] | | ||
| Policy Set Definitions | [`Microsoft.Authorization/policySetDefinitions`][arm_policy_set_definition] | [`azurerm_policy_set_definition`][azurerm_policy_set_definition] | | ||
| Role Assignments | [`Microsoft.Authorization/roleAssignments`][arm_role_assignment] | [`azurerm_role_assignment`][azurerm_role_assignment] | | ||
| Role Definitions | [`Microsoft.Authorization/roleDefinitions`][arm_role_definition] | [`azurerm_role_definition`][azurerm_role_definition] | | ||
|
||
## Usage in Terraform 0.13 | ||
|
||
|
@@ -58,6 +38,8 @@ To use this module with all default settings, please include the following in yo | |
> | ||
> 3. If using the `azurerm_subscription` data source to provide a `tenant_id` value from the current context for `root_parent_id`, you are likely to get a warning that Terraform cannot determine the number of resources to create during the `plan` stage. To avoid the need to use `terraform apply -target=resource` or putting such values in source code, we recommend providing the `root_parent_id` value explicitly via the command-line using `-var 'root_parent_id={{ tenant_id }}'` or your preferred method of injecting variable values at runtime. | ||
### Simple Example | ||
|
||
```hcl | ||
provider "azurerm" { | ||
version = ">= 2.31.1" | ||
|
@@ -71,13 +53,15 @@ variable "tenant_id" { | |
module "enterprise_scale" { | ||
source = "Azure/caf-enterprise-scale/azurerm" | ||
version = "0.0.6-preview" | ||
version = "0.0.7-preview" | ||
root_parent_id = var.tenant_id | ||
} | ||
``` | ||
|
||
### Advanced Example | ||
|
||
To customise the module, you can add any of the following optional variables: | ||
|
||
```hcl | ||
|
@@ -93,7 +77,7 @@ variable "tenant_id" { | |
module "enterprise_scale" { | ||
source = "Azure/caf-enterprise-scale/azurerm" | ||
version = "0.0.6-preview" | ||
version = "0.0.7-preview" | ||
# Mandatory Variables | ||
root_parent_id = var.tenant_id | ||
|
@@ -193,7 +177,7 @@ module "enterprise_scale" { | |
# parameters = {} | ||
# access_control = {} | ||
# } | ||
# landing_zones = { | ||
# landing-zones = { | ||
# archetype_id = "es_landing_zones" | ||
# parameters = {} | ||
# access_control = {} | ||
|
@@ -218,17 +202,17 @@ module "enterprise_scale" { | |
# parameters = {} | ||
# access_control = {} | ||
# } | ||
# demo_corp = { | ||
# demo-corp = { | ||
# archetype_id = "es_demo_corp" | ||
# parameters = {} | ||
# access_control = {} | ||
# } | ||
# demo_online = { | ||
# demo-online = { | ||
# archetype_id = "es_demo_online" | ||
# parameters = {} | ||
# access_control = {} | ||
# } | ||
# demo_sap = { | ||
# demo-sap = { | ||
# archetype_id = "es_demo_sap" | ||
# parameters = {} | ||
# access_control = {} | ||
|
@@ -293,6 +277,109 @@ module "enterprise_scale" { | |
``` | ||
|
||
## Guide to further customisation | ||
|
||
This module contains a default library containing templates for the default Enterprise-scale Archetype Definitions, Policy Assignments, Policy Definitions, Policy Set Definitions (Initiatives), Role Assignments and Role Definitions. These can be added to and overridden by creating a custom library within your root module. Further details of this are provided in the following sections. | ||
|
||
### What is an archetype? | ||
|
||
Archetypes are used in the Enterprise-scale architecture to describe the Landing Zone configuration using a template-driven approach. The archetype is what fundamentally transforms ***Management Groups*** and ***Subscriptions*** into ***Landing Zones***. | ||
|
||
An archetype defines which Azure Policy and Access control (IAM) settings are needed to secure and configure the Landing Zones with everything needed for safe handover to the Landing Zone owner. This covers critical platform controls and configuration items, such as: | ||
|
||
- Consistent role-based access control (RBAC) settings | ||
- Guardrails for security settings | ||
- Guardrails for common workload configurations (e.g. SAP, AKS, WVD, etc.) | ||
- Automate provisioning of critical platform resources such as monitoring and networking solutions in each Landing Zone | ||
|
||
This approach provides improved autonomy for application teams, whilst ensuring security policies and standards are enforced. | ||
|
||
### Working with archetype definitions and the custom library | ||
|
||
The `archetype_definition` is a simple template file written in JSON or YAML. The default archetype definitions can be found in the [built-in module library][TFAES-Library], but custom archetype definitions can also be added to a custom library in the root module. The archetype definition is associated to the scope (i.e. Management Group) by specifying the `archetype_id` within the ***Landing Zone*** configuration object. | ||
|
||
Both the built-in and custom libraries are also used to store ARM based templates for the Policy Assignments, Policy Definitions, Policy Set Definitions (Initiatives) and Role Definitions. Role Assignments are an exception as these are defined as part of the `archetype_config` instead. | ||
|
||
To use a custom library, simply create a folder in your root module (e.g. `/lib`) and tell the module about it using the `library_path` variable (e.g. `library_path = "${path.root}/lib"`). Save your custom templates in the custom library location and as long as they are valid templates for the resource type and match the following naming conventions, the module will automatically import and use them: | ||
|
||
| Resource Type | File Name Pattern | | ||
| ------------- | ----------------- | | ||
| Archetype Definitions | `archetype_definition_*.{json,yml,yaml}` | | ||
| Policy Assignments | `policy_assignment_*.{json,yml,yaml}` | | ||
| Policy Definitions | `policy_definition_*.{json,yml,yaml}` | | ||
| Policy Set Definitions | `policy_set_definition_*.{json,yml,yaml}` | | ||
| Role Definitions | `role_definition_*.{json,yml,yaml}` | | ||
|
||
> The decision to store Policy Assignments, Policy Definitions, Policy Set Definitions (Initiatives) and Role Definitions as native ARM was based on a couple of factors: | ||
> | ||
>- Policies in Terraform require you to understand how to write significant sections of the resource configuration in the native ARM format, and then convert this to a JSON string within Terraform resource. | ||
>- This makes copying these items between ARM templates and Terraform much easier. | ||
>- Terraform doesn't support importing data objects from native Terraform file formats (`.hcl`, `.tf` or `.tfvar`) so we had to use an alternative to be able to support the custom library model for extensibility and customisation.<br>**PRO TIP:** The module also supports YAML for these files as long as they match the ARM schema, although we don't know why you would want to do that! | ||
> | ||
This template driven approach is designed to simplify the process of defining an archetype and forms the foundations for how the module is able to provide feature-rich defaults, whilst also allowing a great degree of extensibility and customisation through the input variables instead of having to fork and modify the module. | ||
|
||
The `archetype_definition` template contains lists of the Policy Assignments, Policy Definitions, Policy Set Definitions (Initiatives) and Role Definitions you want to create when assigning the archetype to a Management Group. It also includes the ability to set default values for parameters associated with Policy Assignments, and set default Role Assignments. | ||
|
||
To keep the `archetype_definition` template as lean as possible, we simply declare the value of the `name` field from the resource templates (by type). The exception is Role Definitions which must have a GUID for the `name` field, so we use the `roleName` value from `properties` instead. | ||
|
||
As long as you follows these patterns, you can create your own archetype definitions to start advanced customisation of your Enterprise-scale deployment. | ||
|
||
This template-based approach was chosen to make the desired-state easier to understand, simplify the process of managing configuration and versioning, reduce code duplication (DRY), and to improve consistency in complex environments. | ||
|
||
#### Example archetype definition | ||
|
||
```json | ||
{ | ||
"archetype_id": { | ||
"policy_assignments": [ | ||
// list of Policy Assignment names | ||
], | ||
"policy_definitions": [ | ||
// list of Policy Definition names | ||
], | ||
"policy_set_definitions": [ | ||
// list of Policy Set Definition names | ||
], | ||
"role_definitions": [ | ||
// list of Role Definition names | ||
], | ||
"archetype_config": { | ||
"parameters": { | ||
// map of parameter objects, grouped by Policy Assignment name | ||
}, | ||
"access_control": { | ||
// map of Role Assignments to create, grouped by Role Definition name | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
#### Using the `default_empty` archetype definition | ||
|
||
The default library includes a `default_empty` archetype definition which is useful when defining Management Groups which only require Role Assignments, or are being used for logical segregation of Landing Zones under a parent arcehtype. You can assign this to any Landing Zone definition, using the `archetype_config` > `archetype_id` value as per the following `custom_landing_zones` example: | ||
|
||
```hcl | ||
custom_landing_zones = { | ||
example-landing-zone-id = { | ||
display_name = "Example Landing Zone" | ||
parent_management_group_id = "tf-landing-zones" | ||
subscription_ids = [] | ||
archetype_config = { | ||
archetype_id = "default_empty" | ||
parameters = {} | ||
access_control = {} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
This is equivalent to creating a standard Management Group without creating any custom Policy Assignments, Policy Definitions, Policy Set Definitions (Initiatives) or Role Definitions. | ||
|
||
Role Assignments can be created using the `archetype_config` > `access_control` object within the `custom_landing_zones` instance. | ||
|
||
> Note that you still need to provide a full and valid Landing Zone object as per the example above. | ||
## License | ||
|
||
|
@@ -341,3 +428,4 @@ contact [[email protected]](mailto:[email protected]) with any additio | |
[azurerm_role_definition]: https://www.terraform.io/docs/providers/azurerm/r/role_definition.html | ||
|
||
[TFAES-LICENSE]: https://github.com/Azure/terraform-azurerm-enterprise-scale/blob/main/LICENSE | ||
[TFAES-Library]: https://github.com/Azure/terraform-azurerm-caf-enterprise-scale/tree/main/modules/terraform-azurerm-caf-enterprise-scale-archetypes/lib |
12 changes: 12 additions & 0 deletions
12
...aform-azurerm-caf-enterprise-scale-archetypes/lib/archetype_definition_default_empty.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"default_empty": { | ||
"policy_assignments": [], | ||
"policy_definitions": [], | ||
"policy_set_definitions": [], | ||
"role_definitions": [], | ||
"archetype_config": { | ||
"parameters": {}, | ||
"access_control": {} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters