diff --git a/README.md b/README.md index 0d52c19..4e5e10e 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,4 @@ -# terraform-azurerm-avm-template - -This is a template repo for Terraform Azure Verified Modules. - -Things to do: - -1. Set up a GitHub repo environment called `test`. -1. Configure environment protection rule to ensure that approval is required before deploying to this environment. -1. Create a user-assigned managed identity in your test subscription. -1. Create a role assignment for the managed identity on your test subscription, use the minimum required role. -1. Configure federated identity credentials on the user assigned managed identity. Use the GitHub environment. -1. Search and update TODOs within the code and remove the TODO comments once complete. - > [!IMPORTANT] > As the overall AVM framework is not GA (generally available) yet - the CI framework and test automation is not fully functional and implemented across all supported languages yet - breaking changes are expected, and additional customer feedback is yet to be gathered and incorporated. Hence, modules **MUST NOT** be published at version `1.0.0` or higher at this time. > @@ -24,7 +11,7 @@ Things to do: The following requirements are needed by this module: -- [terraform](#requirement\_terraform) (~> 1.5) +- [terraform](#requirement\_terraform) (~> 1.7) - [azurerm](#requirement\_azurerm) (~> 3.71) @@ -42,20 +29,27 @@ The following providers are used by this module: The following resources are used by this module: +- [azurerm_managed_disk.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/managed_disk) (resource) - [azurerm_management_lock.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/management_lock) (resource) - [azurerm_private_endpoint.this_managed_dns_zone_groups](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint) (resource) - [azurerm_private_endpoint.this_unmanaged_dns_zone_groups](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint) (resource) - [azurerm_private_endpoint_application_security_group_association.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_endpoint_application_security_group_association) (resource) -- [azurerm_resource_group.TODO](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) (resource) - [azurerm_resource_group_template_deployment.telemetry](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group_template_deployment) (resource) - [azurerm_role_assignment.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/role_assignment) (resource) - [random_id.telem](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) (resource) +- [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) (data source) ## Required Inputs The following input variables are required: +### [create\_option](#input\_create\_option) + +Description: (Required) The method to use when creating the managed disk. Changing this forces a new resource to be created. Possible values include: * `Import` + +Type: `string` + ### [location](#input\_location) Description: Azure region where the resource should be deployed. @@ -74,6 +68,12 @@ Description: The resource group where the resources will be deployed. Type: `string` +### [storage\_account\_type](#input\_storage\_account\_type) + +Description: (Required) The type of storage to use for the managed disk. Possible values are `Standard_LRS`, `StandardSSD_ZRS`, `Premium_LRS`, `PremiumV2_LRS`, `Premium_ZRS`, `StandardSSD_LRS` or `UltraSSD_LRS`. + +Type: `string` + ## Optional Inputs The following input variables are optional (have default values): @@ -136,6 +136,70 @@ map(object({ Default: `{}` +### [disk\_access\_id](#input\_disk\_access\_id) + +Description: (Optional) The ID of the disk access resource for using private endpoints on disks. + +Type: `string` + +Default: `null` + +### [disk\_encryption\_set\_id](#input\_disk\_encryption\_set\_id) + +Description: (Optional) The ID of a Disk Encryption Set which should be used to encrypt this Managed Disk. Conflicts with `secure_vm_disk_encryption_set_id`. + +Type: `string` + +Default: `null` + +### [disk\_iops\_read\_only](#input\_disk\_iops\_read\_only) + +Description: (Optional) The number of IOPS allowed across all VMs mounting the shared disk as read-only; only settable for UltraSSD disks and PremiumV2 disks with shared disk enabled. One operation can transfer between 4k and 256k bytes. + +Type: `number` + +Default: `null` + +### [disk\_iops\_read\_write](#input\_disk\_iops\_read\_write) + +Description: (Optional) The number of IOPS allowed for this disk; only settable for UltraSSD disks and PremiumV2 disks. One operation can transfer between 4k and 256k bytes. + +Type: `number` + +Default: `null` + +### [disk\_mbps\_read\_only](#input\_disk\_mbps\_read\_only) + +Description: (Optional) The bandwidth allowed across all VMs mounting the shared disk as read-only; only settable for UltraSSD disks and PremiumV2 disks with shared disk enabled. MBps means millions of bytes per second. + +Type: `number` + +Default: `null` + +### [disk\_mbps\_read\_write](#input\_disk\_mbps\_read\_write) + +Description: (Optional) The bandwidth allowed for this disk; only settable for UltraSSD disks and PremiumV2 disks. MBps means millions of bytes per second. + +Type: `number` + +Default: `null` + +### [disk\_size\_gb](#input\_disk\_size\_gb) + +Description: (Optional) (Optional, Required for a new managed disk) Specifies the size of the managed disk to create in gigabytes. If `create_option` is `Copy` or `FromImage`, then the value must be equal to or greater than the source's size. The size can only be increased. + +Type: `number` + +Default: `null` + +### [edge\_zone](#input\_edge\_zone) + +Description: (Optional) Specifies the Edge Zone within the Azure Region where this Managed Disk should exist. Changing this forces a new Managed Disk to be created. + +Type: `string` + +Default: `null` + ### [enable\_telemetry](#input\_enable\_telemetry) Description: This variable controls whether or not telemetry is enabled for the module. @@ -146,6 +210,62 @@ Type: `bool` Default: `true` +### [encryption\_settings](#input\_encryption\_settings) + +Description: - `enabled` - + +--- +`disk_encryption_key` block supports the following: +- `secret_url` - (Required) The URL to the Key Vault Secret used as the Disk Encryption Key. This can be found as `id` on the `azurerm_key_vault_secret` resource. +- `source_vault_id` - (Required) The ID of the source Key Vault. This can be found as `id` on the `azurerm_key_vault` resource. + +--- +`key_encryption_key` block supports the following: +- `key_url` - (Required) The URL to the Key Vault Key used as the Key Encryption Key. This can be found as `id` on the `azurerm_key_vault_key` resource. +- `source_vault_id` - (Required) The ID of the source Key Vault. This can be found as `id` on the `azurerm_key_vault` resource. + +Type: + +```hcl +object({ + enabled = optional(bool) + disk_encryption_key = optional(object({ + secret_url = string + source_vault_id = string + })) + key_encryption_key = optional(object({ + key_url = string + source_vault_id = string + })) + }) +``` + +Default: `null` + +### [gallery\_image\_reference\_id](#input\_gallery\_image\_reference\_id) + +Description: (Optional) ID of a Gallery Image Version to copy when `create_option` is `FromImage`. This field cannot be specified if image\_reference\_id is specified. Changing this forces a new resource to be created. + +Type: `string` + +Default: `null` + +### [hyper\_v\_generation](#input\_hyper\_v\_generation) + +Description: (Optional) The HyperV Generation of the Disk when the source of an `Import` or `Copy` operation targets a source that contains an operating system. Possible values are `V1` and `V2`. For `ImportSecure` it must be set to `V2`. Changing this forces a new resource to be created. + +Type: `string` + +Default: `null` + +### [image\_reference\_id](#input\_image\_reference\_id) + +Description: (Optional) ID of an existing platform/marketplace disk image to copy when `create_option` is `FromImage`. This field cannot be specified if gallery\_image\_reference\_id is specified. Changing this forces a new resource to be created. + +Type: `string` + +Default: `null` + ### [lock](#input\_lock) Description: Controls the Resource Lock configuration for this resource. The following properties can be specified: @@ -164,64 +284,95 @@ object({ Default: `null` -### [managed\_identities](#input\_managed\_identities) +### [logical\_sector\_size](#input\_logical\_sector\_size) -Description: Controls the Managed Identity configuration on this resource. The following properties can be specified: +Description: (Optional) Logical Sector Size. Possible values are: `512` and `4096`. Defaults to `4096`. Changing this forces a new resource to be created. -- `system_assigned` - (Optional) Specifies if the System Assigned Managed Identity should be enabled. -- `user_assigned_resource_ids` - (Optional) Specifies a list of User Assigned Managed Identity resource IDs to be assigned to this resource. +Type: `number` -Type: +Default: `null` -```hcl -object({ - system_assigned = optional(bool, false) - user_assigned_resource_ids = optional(set(string), []) - }) -``` +### [max\_shares](#input\_max\_shares) -Default: `{}` +Description: (Optional) The maximum number of VMs that can attach to the disk at the same time. Value greater than one indicates a disk that can be mounted on multiple VMs at the same time. + +Type: `number` + +Default: `null` + +### [network\_access\_policy](#input\_network\_access\_policy) + +Description: (Optional) Policy for accessing the disk via network. Allowed values are `AllowAll`, `AllowPrivate`, and `DenyAll`. + +Type: `string` + +Default: `null` + +### [on\_demand\_bursting\_enabled](#input\_on\_demand\_bursting\_enabled) + +Description: (Optional) Specifies if On-Demand Bursting is enabled for the Managed Disk. + +Type: `bool` + +Default: `null` + +### [optimized\_frequent\_attach\_enabled](#input\_optimized\_frequent\_attach\_enabled) + +Description: (Optional) Specifies whether this Managed Disk should be optimized for frequent disk attachments (where a disk is attached/detached more than 5 times in a day). Defaults to `false`. + +Type: `bool` + +Default: `null` + +### [os\_type](#input\_os\_type) + +Description: (Optional) Specify a value when the source of an `Import`, `ImportSecure` or `Copy` operation targets a source that contains an operating system. Valid values are `Linux` or `Windows`. + +Type: `string` + +Default: `null` + +### [performance\_plus\_enabled](#input\_performance\_plus\_enabled) + +Description: (Optional) Specifies whether Performance Plus is enabled for this Managed Disk. Defaults to `false`. Changing this forces a new resource to be created. + +Type: `bool` + +Default: `null` ### [private\_endpoints](#input\_private\_endpoints) -Description: A map of private endpoints to create on this resource. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time. - -- `name` - (Optional) The name of the private endpoint. One will be generated if not set. -- `role_assignments` - (Optional) A map of role assignments to create on the private endpoint. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time. See `var.role_assignments` for more information. -- `lock` - (Optional) The lock level to apply to the private endpoint. Default is `None`. Possible values are `None`, `CanNotDelete`, and `ReadOnly`. -- `tags` - (Optional) A mapping of tags to assign to the private endpoint. -- `subnet_resource_id` - The resource ID of the subnet to deploy the private endpoint in. -- `private_dns_zone_group_name` - (Optional) The name of the private DNS zone group. One will be generated if not set. -- `private_dns_zone_resource_ids` - (Optional) A set of resource IDs of private DNS zones to associate with the private endpoint. If not set, no zone groups will be created and the private endpoint will not be associated with any private DNS zones. DNS records must be managed external to this module. -- `application_security_group_resource_ids` - (Optional) A map of resource IDs of application security groups to associate with the private endpoint. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time. -- `private_service_connection_name` - (Optional) The name of the private service connection. One will be generated if not set. -- `network_interface_name` - (Optional) The name of the network interface. One will be generated if not set. -- `location` - (Optional) The Azure location where the resources will be deployed. Defaults to the location of the resource group. -- `resource_group_name` - (Optional) The resource group where the resources will be deployed. Defaults to the resource group of this resource. -- `ip_configurations` - (Optional) A map of IP configurations to create on the private endpoint. If not specified the platform will create one. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time. - - `name` - The name of the IP configuration. - - `private_ip_address` - The private IP address of the IP configuration. +Description: A map of private endpoints to create on the Key Vault. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time. + + - `name` - (Optional) The name of the private endpoint. One will be generated if not set. + - `role_assignments` - (Optional) A map of role assignments to create on the private endpoint. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time. See `var.role_assignments` for more information. + - `lock` - (Optional) The lock level to apply to the private endpoint. Default is `None`. Possible values are `None`, `CanNotDelete`, and `ReadOnly`. + - `tags` - (Optional) A mapping of tags to assign to the private endpoint. + - `subnet_resource_id` - The resource ID of the subnet to deploy the private endpoint in. + - `private_dns_zone_group_name` - (Optional) The name of the private DNS zone group. One will be generated if not set. + - `private_dns_zone_resource_ids` - (Optional) A set of resource IDs of private DNS zones to associate with the private endpoint. If not set, no zone groups will be created and the private endpoint will not be associated with any private DNS zones. DNS records must be managed external to this module. + - `application_security_group_resource_ids` - (Optional) A map of resource IDs of application security groups to associate with the private endpoint. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time. + - `private_service_connection_name` - (Optional) The name of the private service connection. One will be generated if not set. + - `network_interface_name` - (Optional) The name of the network interface. One will be generated if not set. + - `location` - (Optional) The Azure location where the resources will be deployed. Defaults to the location of the resource group. + - `resource_group_name` - (Optional) The resource group where the resources will be deployed. Defaults to the resource group of the Key Vault. + - `ip_configurations` - (Optional) A map of IP configurations to create on the private endpoint. If not specified the platform will create one. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time. + - `name` - The name of the IP configuration. + - `private_ip_address` - The private IP address of the IP configuration. Type: ```hcl map(object({ - name = optional(string, null) - role_assignments = optional(map(object({ - role_definition_id_or_name = string - principal_id = string - description = optional(string, null) - skip_service_principal_aad_check = optional(bool, false) - condition = optional(string, null) - condition_version = optional(string, null) - delegated_managed_identity_resource_id = optional(string, null) - })), {}) - lock = optional(object({ - kind = string - name = optional(string, null) - }), null) - tags = optional(map(string), null) - subnet_resource_id = string + name = optional(string, null) + role_assignments = optional(map(object({})), {}) # see https://azure.github.io/Azure-Verified-Modules/Azure-Verified-Modules/specs/shared/interfaces/#role-assignments + lock = optional(object({}), {}) # see https://azure.github.io/Azure-Verified-Modules/Azure-Verified-Modules/specs/shared/interfaces/#resource-locks + tags = optional(map(any), null) # see https://azure.github.io/Azure-Verified-Modules/Azure-Verified-Modules/specs/shared/interfaces/#tags + subnet_resource_id = string + ## You only need to expose the subresource_name if there are multiple underlying services, e.g. storage. + ## Which has blob, file, etc. + ## If there is only one then leave this out and hardcode the value in the module. + # subresource_name = string private_dns_zone_group_name = optional(string, "default") private_dns_zone_resource_ids = optional(set(string), []) application_security_group_associations = optional(map(string), {}) @@ -246,6 +397,14 @@ Type: `bool` Default: `true` +### [public\_network\_access\_enabled](#input\_public\_network\_access\_enabled) + +Description: (Optional) Whether it is allowed to access the disk via public network. Defaults to `true`. + +Type: `bool` + +Default: `null` + ### [role\_assignments](#input\_role\_assignments) Description: A map of role assignments to create on this resource. The map key is deliberately arbitrary to avoid issues where map keys maybe unknown at plan time. @@ -275,6 +434,46 @@ map(object({ Default: `{}` +### [secure\_vm\_disk\_encryption\_set\_id](#input\_secure\_vm\_disk\_encryption\_set\_id) + +Description: (Optional) The ID of the Disk Encryption Set which should be used to Encrypt this OS Disk when the Virtual Machine is a Confidential VM. Conflicts with `disk_encryption_set_id`. Changing this forces a new resource to be created. + +Type: `string` + +Default: `null` + +### [security\_type](#input\_security\_type) + +Description: (Optional) Security Type of the Managed Disk when it is used for a Confidential VM. Possible values are `ConfidentialVM_VMGuestStateOnlyEncryptedWithPlatformKey`, `ConfidentialVM_DiskEncryptedWithPlatformKey` and `ConfidentialVM_DiskEncryptedWithCustomerKey`. Changing this forces a new resource to be created. + +Type: `string` + +Default: `null` + +### [source\_resource\_id](#input\_source\_resource\_id) + +Description: (Optional) The ID of an existing Managed Disk or Snapshot to copy when `create_option` is `Copy` or the recovery point to restore when `create_option` is `Restore`. Changing this forces a new resource to be created. + +Type: `string` + +Default: `null` + +### [source\_uri](#input\_source\_uri) + +Description: (Optional) URI to a valid VHD file to be used when `create_option` is `Import` or `ImportSecure`. Changing this forces a new resource to be created. + +Type: `string` + +Default: `null` + +### [storage\_account\_id](#input\_storage\_account\_id) + +Description: (Optional) The ID of the Storage Account where the `source_uri` is located. Required when `create_option` is set to `Import` or `ImportSecure`. Changing this forces a new resource to be created. + +Type: `string` + +Default: `null` + ### [tags](#input\_tags) Description: (Optional) Tags of the resource. @@ -283,18 +482,58 @@ Type: `map(string)` Default: `null` +### [tier](#input\_tier) + +Description: (Optional) The disk performance tier to use. Possible values are documented [here](https://docs.microsoft.com/azure/virtual-machines/disks-change-performance). This feature is currently supported only for premium SSDs. + +Type: `string` + +Default: `null` + +### [trusted\_launch\_enabled](#input\_trusted\_launch\_enabled) + +Description: (Optional) Specifies if Trusted Launch is enabled for the Managed Disk. Changing this forces a new resource to be created. + +Type: `bool` + +Default: `null` + +### [upload\_size\_bytes](#input\_upload\_size\_bytes) + +Description: (Optional) Specifies the size of the managed disk to create in bytes. Required when `create_option` is `Upload`. The value must be equal to the source disk to be copied in bytes. Source disk size could be calculated with `ls -l` or `wc -c`. More information can be found at [Copy a managed disk](https://learn.microsoft.com/en-us/azure/virtual-machines/linux/disks-upload-vhd-to-managed-disk-cli#copy-a-managed-disk). Changing this forces a new resource to be created. + +Type: `number` + +Default: `null` + +### [zone](#input\_zone) + +Description: (Optional) Specifies the Availability Zone in which this Managed Disk should be located. Changing this property forces a new resource to be created. + +Type: `string` + +Default: `null` + ## Outputs The following outputs are exported: +### [location](#output\_location) + +Description: The deployment region. + ### [private\_endpoints](#output\_private\_endpoints) -Description: A map of the private endpoints created. +Description: A map of the private endpoints created. ### [resource](#output\_resource) Description: This is the full output for the resource. +### [resource\_group\_name](#output\_resource\_group\_name) + +Description: The name of the Resource Group. + ## Modules No modules. diff --git a/_header.md b/_header.md index 518d2f6..a2b6f07 100644 --- a/_header.md +++ b/_header.md @@ -1,16 +1,3 @@ -# terraform-azurerm-avm-template - -This is a template repo for Terraform Azure Verified Modules. - -Things to do: - -1. Set up a GitHub repo environment called `test`. -1. Configure environment protection rule to ensure that approval is required before deploying to this environment. -1. Create a user-assigned managed identity in your test subscription. -1. Create a role assignment for the managed identity on your test subscription, use the minimum required role. -1. Configure federated identity credentials on the user assigned managed identity. Use the GitHub environment. -1. Search and update TODOs within the code and remove the TODO comments once complete. - > [!IMPORTANT] > As the overall AVM framework is not GA (generally available) yet - the CI framework and test automation is not fully functional and implemented across all supported languages yet - breaking changes are expected, and additional customer feedback is yet to be gathered and incorporated. Hence, modules **MUST NOT** be published at version `1.0.0` or higher at this time. > diff --git a/examples/default/README.md b/examples/default/README.md index 1abcc3c..28932ef 100644 --- a/examples/default/README.md +++ b/examples/default/README.md @@ -4,25 +4,6 @@ This deploys the module in its simplest form. ```hcl -terraform { - required_version = "~> 1.5" - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "~> 3.74" - } - random = { - source = "hashicorp/random" - version = "~> 3.5" - } - } -} - -provider "azurerm" { - features {} -} - - ## Section to provide a random Azure region for the resource group # This allows us to randomize the region for the resource group. module "regions" { @@ -47,21 +28,40 @@ module "naming" { resource "azurerm_resource_group" "this" { location = module.regions.regions[random_integer.region_index.result].name name = module.naming.resource_group.name_unique + tags = local.tags } +data "azurerm_client_config" "current" {} + # This is the module call -# Do not specify location here due to the randomization above. -# Leaving location as `null` will cause the module to use the resource group location -# with a data source. -module "test" { +module "disk" { source = "../../" - # source = "Azure/avm--/azurerm" + # source = "Azure/avm-res-compute-disk/azurerm" # ... location = azurerm_resource_group.this.location - name = "TODO" # TODO update with module.naming..name_unique + name = module.naming.managed_disk.name_unique resource_group_name = azurerm_resource_group.this.name - enable_telemetry = var.enable_telemetry # see variables.tf + enable_telemetry = var.enable_telemetry # see variables.tf + create_option = "Empty" + storage_account_type = "PremiumV2_LRS" + disk_size_gb = 1024 + tags = local.tags + + # Uncomment the code below to implement a VMSS Lock + #lock = { + # name = "VMSSNoDelete" + # kind = "CanNotDelete" + #} + + // Example role assignment + role_assignments = { + role_assignment = { + principal_id = data.azurerm_client_config.current.object_id + role_definition_id_or_name = "Reader" + description = "Assign the Reader role to the deployment user on this disk resource scope." + } + } } ``` @@ -70,7 +70,7 @@ module "test" { The following requirements are needed by this module: -- [terraform](#requirement\_terraform) (~> 1.5) +- [terraform](#requirement\_terraform) (~> 1.7) - [azurerm](#requirement\_azurerm) (~> 3.74) @@ -90,6 +90,7 @@ The following resources are used by this module: - [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) (resource) - [random_integer.region_index](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) (resource) +- [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) (data source) ## Required Inputs @@ -112,12 +113,30 @@ Default: `true` ## Outputs -No outputs. +The following outputs are exported: + +### [location](#output\_location) + +Description: The deployment region. + +### [resource](#output\_resource) + +Description: This is the full output for the resource. + +### [resource\_group\_name](#output\_resource\_group\_name) + +Description: The name of the Resource Group. ## Modules The following Modules are called: +### [disk](#module\_disk) + +Source: ../../ + +Version: + ### [naming](#module\_naming) Source: Azure/naming/azurerm @@ -130,12 +149,6 @@ Source: Azure/regions/azurerm Version: ~> 0.3 -### [test](#module\_test) - -Source: ../../ - -Version: - ## Data Collection diff --git a/examples/default/locals.tf b/examples/default/locals.tf new file mode 100644 index 0000000..cfb73e1 --- /dev/null +++ b/examples/default/locals.tf @@ -0,0 +1,5 @@ +locals { + tags = { + scenario = "Disk Default AVM Sample" + } +} \ No newline at end of file diff --git a/examples/default/main.tf b/examples/default/main.tf index 38cdd38..8db8d1c 100644 --- a/examples/default/main.tf +++ b/examples/default/main.tf @@ -1,22 +1,3 @@ -terraform { - required_version = "~> 1.5" - required_providers { - azurerm = { - source = "hashicorp/azurerm" - version = "~> 3.74" - } - random = { - source = "hashicorp/random" - version = "~> 3.5" - } - } -} - -provider "azurerm" { - features {} -} - - ## Section to provide a random Azure region for the resource group # This allows us to randomize the region for the resource group. module "regions" { @@ -41,19 +22,38 @@ module "naming" { resource "azurerm_resource_group" "this" { location = module.regions.regions[random_integer.region_index.result].name name = module.naming.resource_group.name_unique + tags = local.tags } +data "azurerm_client_config" "current" {} + # This is the module call -# Do not specify location here due to the randomization above. -# Leaving location as `null` will cause the module to use the resource group location -# with a data source. -module "test" { +module "disk" { source = "../../" - # source = "Azure/avm--/azurerm" + # source = "Azure/avm-res-compute-disk/azurerm" # ... location = azurerm_resource_group.this.location - name = "TODO" # TODO update with module.naming..name_unique + name = module.naming.managed_disk.name_unique resource_group_name = azurerm_resource_group.this.name - enable_telemetry = var.enable_telemetry # see variables.tf + enable_telemetry = var.enable_telemetry # see variables.tf + create_option = "Empty" + storage_account_type = "PremiumV2_LRS" + disk_size_gb = 1024 + tags = local.tags + + # Uncomment the code below to implement a VMSS Lock + #lock = { + # name = "VMSSNoDelete" + # kind = "CanNotDelete" + #} + + // Example role assignment + role_assignments = { + role_assignment = { + principal_id = data.azurerm_client_config.current.object_id + role_definition_id_or_name = "Reader" + description = "Assign the Reader role to the deployment user on this disk resource scope." + } + } } diff --git a/examples/default/outputs.tf b/examples/default/outputs.tf new file mode 100644 index 0000000..d204d79 --- /dev/null +++ b/examples/default/outputs.tf @@ -0,0 +1,14 @@ +output "location" { + description = "The deployment region." + value = module.disk.location +} + +output "resource" { + description = "This is the full output for the resource." + value = module.disk.resource +} + +output "resource_group_name" { + description = "The name of the Resource Group." + value = module.disk.resource_group_name +} diff --git a/examples/default/terraform.tf b/examples/default/terraform.tf new file mode 100644 index 0000000..8dc4e9e --- /dev/null +++ b/examples/default/terraform.tf @@ -0,0 +1,19 @@ +terraform { + required_version = "~> 1.7" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.74" + } + random = { + source = "hashicorp/random" + version = "~> 3.5" + } + } +} + +provider "azurerm" { + features {} +} + + diff --git a/examples/diagnostic-settings/README.md b/examples/diagnostic-settings/README.md new file mode 100644 index 0000000..44a3922 --- /dev/null +++ b/examples/diagnostic-settings/README.md @@ -0,0 +1,150 @@ + +# Default example + +This deploys the module with diagnostic settings enabled. + +```hcl +# This allows us to randomize the region for the resource group. +module "regions" { + source = "Azure/regions/azurerm" + version = ">= 0.3.0" +} + +# This allows us to randomize the region for the resource group. +resource "random_integer" "region_index" { + max = length(module.regions.regions) - 1 + min = 0 +} + +# This ensures we have unique CAF compliant names for our resources. +module "naming" { + source = "Azure/naming/azurerm" + version = "0.3.0" +} + +# This is required for resource modules +resource "azurerm_resource_group" "this" { + location = module.regions.regions[random_integer.region_index.result].name + name = module.naming.resource_group.name_unique + tags = local.tags +} + +resource "azurerm_log_analytics_workspace" "this" { + location = azurerm_resource_group.this.location + name = module.naming.log_analytics_workspace.name_unique + resource_group_name = azurerm_resource_group.this.name + tags = local.tags +} + +# This is the module call +module "disk" { + source = "../../" + # source = "Azure/avm-res-compute-disk/azurerm" + # ... + location = azurerm_resource_group.this.location + name = module.naming.managed_disk.name_unique + resource_group_name = azurerm_resource_group.this.name + + enable_telemetry = var.enable_telemetry # see variables.tf + create_option = "Empty" + storage_account_type = "PremiumV2_LRS" + disk_size_gb = 1024 + tags = local.tags + diagnostic_settings = { + to_la = { + name = "to-la" + workspace_resource_id = azurerm_log_analytics_workspace.this.id + } + } +} +``` + + +## Requirements + +The following requirements are needed by this module: + +- [terraform](#requirement\_terraform) (~> 1.7) + +- [azurerm](#requirement\_azurerm) (~> 3.74) + +- [random](#requirement\_random) (~> 3.5) + +## Providers + +The following providers are used by this module: + +- [azurerm](#provider\_azurerm) (~> 3.74) + +- [random](#provider\_random) (~> 3.5) + +## Resources + +The following resources are used by this module: + +- [azurerm_log_analytics_workspace.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/log_analytics_workspace) (resource) +- [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) (resource) +- [random_integer.region_index](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) (resource) + + +## Required Inputs + +No required inputs. + +## Optional Inputs + +The following input variables are optional (have default values): + +### [enable\_telemetry](#input\_enable\_telemetry) + +Description: This variable controls whether or not telemetry is enabled for the module. +For more information see https://aka.ms/avm/telemetryinfo. +If it is set to false, then no telemetry will be collected. + +Type: `bool` + +Default: `true` + +## Outputs + +The following outputs are exported: + +### [location](#output\_location) + +Description: The deployment region. + +### [resource](#output\_resource) + +Description: This is the full output for the resource. + +### [resource\_group\_name](#output\_resource\_group\_name) + +Description: The name of the Resource Group. + +## Modules + +The following Modules are called: + +### [disk](#module\_disk) + +Source: ../../ + +Version: + +### [naming](#module\_naming) + +Source: Azure/naming/azurerm + +Version: 0.3.0 + +### [regions](#module\_regions) + +Source: Azure/regions/azurerm + +Version: >= 0.3.0 + + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. + \ No newline at end of file diff --git a/examples/diagnostic-settings/_footer.md b/examples/diagnostic-settings/_footer.md new file mode 100644 index 0000000..bc56bcb --- /dev/null +++ b/examples/diagnostic-settings/_footer.md @@ -0,0 +1,4 @@ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/examples/diagnostic-settings/_header.md b/examples/diagnostic-settings/_header.md new file mode 100644 index 0000000..9e22474 --- /dev/null +++ b/examples/diagnostic-settings/_header.md @@ -0,0 +1,3 @@ +# Default example + +This deploys the module with diagnostic settings enabled. diff --git a/examples/diagnostic-settings/locals.tf b/examples/diagnostic-settings/locals.tf new file mode 100644 index 0000000..06cc9a9 --- /dev/null +++ b/examples/diagnostic-settings/locals.tf @@ -0,0 +1,5 @@ +locals { + tags = { + scenario = "Disk Diagnostic Settings AVM Sample" + } +} \ No newline at end of file diff --git a/examples/diagnostic-settings/main.tf b/examples/diagnostic-settings/main.tf new file mode 100644 index 0000000..6a23e78 --- /dev/null +++ b/examples/diagnostic-settings/main.tf @@ -0,0 +1,53 @@ +# This allows us to randomize the region for the resource group. +module "regions" { + source = "Azure/regions/azurerm" + version = ">= 0.3.0" +} + +# This allows us to randomize the region for the resource group. +resource "random_integer" "region_index" { + max = length(module.regions.regions) - 1 + min = 0 +} + +# This ensures we have unique CAF compliant names for our resources. +module "naming" { + source = "Azure/naming/azurerm" + version = "0.3.0" +} + +# This is required for resource modules +resource "azurerm_resource_group" "this" { + location = module.regions.regions[random_integer.region_index.result].name + name = module.naming.resource_group.name_unique + tags = local.tags +} + +resource "azurerm_log_analytics_workspace" "this" { + location = azurerm_resource_group.this.location + name = module.naming.log_analytics_workspace.name_unique + resource_group_name = azurerm_resource_group.this.name + tags = local.tags +} + +# This is the module call +module "disk" { + source = "../../" + # source = "Azure/avm-res-compute-disk/azurerm" + # ... + location = azurerm_resource_group.this.location + name = module.naming.managed_disk.name_unique + resource_group_name = azurerm_resource_group.this.name + + enable_telemetry = var.enable_telemetry # see variables.tf + create_option = "Empty" + storage_account_type = "PremiumV2_LRS" + disk_size_gb = 1024 + tags = local.tags + diagnostic_settings = { + to_la = { + name = "to-la" + workspace_resource_id = azurerm_log_analytics_workspace.this.id + } + } +} \ No newline at end of file diff --git a/examples/diagnostic-settings/outputs.tf b/examples/diagnostic-settings/outputs.tf new file mode 100644 index 0000000..d204d79 --- /dev/null +++ b/examples/diagnostic-settings/outputs.tf @@ -0,0 +1,14 @@ +output "location" { + description = "The deployment region." + value = module.disk.location +} + +output "resource" { + description = "This is the full output for the resource." + value = module.disk.resource +} + +output "resource_group_name" { + description = "The name of the Resource Group." + value = module.disk.resource_group_name +} diff --git a/examples/diagnostic-settings/terraform.tf b/examples/diagnostic-settings/terraform.tf new file mode 100644 index 0000000..8dc4e9e --- /dev/null +++ b/examples/diagnostic-settings/terraform.tf @@ -0,0 +1,19 @@ +terraform { + required_version = "~> 1.7" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.74" + } + random = { + source = "hashicorp/random" + version = "~> 3.5" + } + } +} + +provider "azurerm" { + features {} +} + + diff --git a/examples/diagnostic-settings/variables.tf b/examples/diagnostic-settings/variables.tf new file mode 100644 index 0000000..1318944 --- /dev/null +++ b/examples/diagnostic-settings/variables.tf @@ -0,0 +1,9 @@ +variable "enable_telemetry" { + type = bool + default = true + description = < +# Default example + +This example deploys an encrypted disk. + +```hcl +# This allows us to randomize the region for the resource group. +module "regions" { + source = "Azure/regions/azurerm" + version = ">= 0.3.0" +} + +# This allows us to randomize the region for the resource group. +resource "random_integer" "region_index" { + max = length(module.regions.regions) - 1 + min = 0 +} + +# This ensures we have unique CAF compliant names for our resources. +module "naming" { + source = "Azure/naming/azurerm" + version = "0.3.0" +} + +# This is required for resource modules +resource "azurerm_resource_group" "this" { + location = module.regions.regions[random_integer.region_index.result].name + name = module.naming.resource_group.name_unique +} + +# This is the module call +module "disk" { + source = "../../" + # source = "Azure/avm-res-compute-disk/azurerm" + # ... + location = azurerm_resource_group.this.location + name = module.naming.managed_disk.name_unique + resource_group_name = azurerm_resource_group.this.name + + enable_telemetry = var.enable_telemetry # see variables.tf + create_option = "Empty" + storage_account_type = "PremiumV2_LRS" + disk_size_gb = 1024 + disk_encryption_set_id = azurerm_disk_encryption_set.this.id +} +``` + + +## Requirements + +The following requirements are needed by this module: + +- [terraform](#requirement\_terraform) (~> 1.7) + +- [azurerm](#requirement\_azurerm) (~> 3.74) + +- [random](#requirement\_random) (~> 3.5) + +## Providers + +The following providers are used by this module: + +- [azurerm](#provider\_azurerm) (~> 3.74) + +- [random](#provider\_random) (~> 3.5) + +## Resources + +The following resources are used by this module: + +- [azurerm_disk_access.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/disk_access) (resource) +- [azurerm_disk_encryption_set.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/disk_encryption_set) (resource) +- [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) (resource) +- [azurerm_user_assigned_identity.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/user_assigned_identity) (resource) +- [random_integer.region_index](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) (resource) +- [azurerm_client_config.current](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/client_config) (data source) + + +## Required Inputs + +No required inputs. + +## Optional Inputs + +The following input variables are optional (have default values): + +### [enable\_telemetry](#input\_enable\_telemetry) + +Description: This variable controls whether or not telemetry is enabled for the module. +For more information see https://aka.ms/avm/telemetryinfo. +If it is set to false, then no telemetry will be collected. + +Type: `bool` + +Default: `true` + +## Outputs + +The following outputs are exported: + +### [location](#output\_location) + +Description: The deployment region. + +### [resource](#output\_resource) + +Description: This is the full output for the resource. + +### [resource\_group\_name](#output\_resource\_group\_name) + +Description: The name of the Resource Group. + +## Modules + +The following Modules are called: + +### [disk](#module\_disk) + +Source: ../../ + +Version: + +### [key\_vault](#module\_key\_vault) + +Source: Azure/avm-res-keyvault-vault/azurerm + +Version: 0.5.3 + +### [naming](#module\_naming) + +Source: Azure/naming/azurerm + +Version: 0.3.0 + +### [regions](#module\_regions) + +Source: Azure/regions/azurerm + +Version: >= 0.3.0 + + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. + \ No newline at end of file diff --git a/examples/encrypted-disk/_footer.md b/examples/encrypted-disk/_footer.md new file mode 100644 index 0000000..bc56bcb --- /dev/null +++ b/examples/encrypted-disk/_footer.md @@ -0,0 +1,4 @@ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/examples/encrypted-disk/_header.md b/examples/encrypted-disk/_header.md new file mode 100644 index 0000000..a6274aa --- /dev/null +++ b/examples/encrypted-disk/_header.md @@ -0,0 +1,3 @@ +# Default example + +This example deploys an encrypted disk. diff --git a/examples/encrypted-disk/dependencies.tf b/examples/encrypted-disk/dependencies.tf new file mode 100644 index 0000000..1f238d8 --- /dev/null +++ b/examples/encrypted-disk/dependencies.tf @@ -0,0 +1,78 @@ +resource "azurerm_disk_access" "this" { + location = azurerm_resource_group.this.location + name = replace(azurerm_resource_group.this.name, "rg", "da") // Naming module does not support disk access + resource_group_name = azurerm_resource_group.this.name + tags = local.tags +} + +data "azurerm_client_config" "current" {} + +resource "azurerm_user_assigned_identity" "this" { + location = azurerm_resource_group.this.location + name = module.naming.user_assigned_identity.name_unique + resource_group_name = azurerm_resource_group.this.name + tags = local.tags +} + +module "key_vault" { + source = "Azure/avm-res-keyvault-vault/azurerm" + version = "0.5.3" + tenant_id = data.azurerm_client_config.current.tenant_id + name = module.naming.key_vault.name_unique + resource_group_name = azurerm_resource_group.this.name + location = azurerm_resource_group.this.location + enabled_for_deployment = true + tags = local.tags + + network_acls = { + default_action = "Allow" + bypass = "AzureServices" + } + + // Role recommended in this article: https://learn.microsoft.com/en-us/azure/virtual-machines/disk-encryption#full-control-of-your-keys + role_assignments = { + key_vault_administrator = { + role_definition_id_or_name = "Key Vault Administrator" + principal_id = data.azurerm_client_config.current.object_id + } + key_vault_crypto_service_encryption_user = { + role_definition_id_or_name = "Key Vault Crypto Service Encryption User" + principal_id = azurerm_user_assigned_identity.this.principal_id + } + } + + keys = { + cmkfordisk = { + key_opts = [ + "decrypt", + "encrypt", + "sign", + "unwrapKey", + "verify", + "wrapKey" + ] + key_type = "RSA" + key_vault_id = module.key_vault.resource.id + name = "cmkfordisk" + key_size = 2048 + tags = local.tags + } + } + + wait_for_rbac_before_secret_operations = { + create = "120s" + } +} + +resource "azurerm_disk_encryption_set" "this" { + key_vault_key_id = module.key_vault.resource_keys["cmkfordisk"].id + location = azurerm_resource_group.this.location + name = module.naming.disk_encryption_set.name_unique + resource_group_name = azurerm_resource_group.this.name + tags = local.tags + + identity { + type = "UserAssigned" + identity_ids = [azurerm_user_assigned_identity.this.id] + } +} diff --git a/examples/encrypted-disk/locals.tf b/examples/encrypted-disk/locals.tf new file mode 100644 index 0000000..33fa1fa --- /dev/null +++ b/examples/encrypted-disk/locals.tf @@ -0,0 +1,5 @@ +locals { + tags = { + scenario = "Disk Encrypted Disk AVM Sample" + } +} \ No newline at end of file diff --git a/examples/encrypted-disk/main.tf b/examples/encrypted-disk/main.tf new file mode 100644 index 0000000..05b09f0 --- /dev/null +++ b/examples/encrypted-disk/main.tf @@ -0,0 +1,39 @@ +# This allows us to randomize the region for the resource group. +module "regions" { + source = "Azure/regions/azurerm" + version = ">= 0.3.0" +} + +# This allows us to randomize the region for the resource group. +resource "random_integer" "region_index" { + max = length(module.regions.regions) - 1 + min = 0 +} + +# This ensures we have unique CAF compliant names for our resources. +module "naming" { + source = "Azure/naming/azurerm" + version = "0.3.0" +} + +# This is required for resource modules +resource "azurerm_resource_group" "this" { + location = module.regions.regions[random_integer.region_index.result].name + name = module.naming.resource_group.name_unique +} + +# This is the module call +module "disk" { + source = "../../" + # source = "Azure/avm-res-compute-disk/azurerm" + # ... + location = azurerm_resource_group.this.location + name = module.naming.managed_disk.name_unique + resource_group_name = azurerm_resource_group.this.name + + enable_telemetry = var.enable_telemetry # see variables.tf + create_option = "Empty" + storage_account_type = "PremiumV2_LRS" + disk_size_gb = 1024 + disk_encryption_set_id = azurerm_disk_encryption_set.this.id +} diff --git a/examples/encrypted-disk/outputs.tf b/examples/encrypted-disk/outputs.tf new file mode 100644 index 0000000..d204d79 --- /dev/null +++ b/examples/encrypted-disk/outputs.tf @@ -0,0 +1,14 @@ +output "location" { + description = "The deployment region." + value = module.disk.location +} + +output "resource" { + description = "This is the full output for the resource." + value = module.disk.resource +} + +output "resource_group_name" { + description = "The name of the Resource Group." + value = module.disk.resource_group_name +} diff --git a/examples/encrypted-disk/terraform.tf b/examples/encrypted-disk/terraform.tf new file mode 100644 index 0000000..8dc4e9e --- /dev/null +++ b/examples/encrypted-disk/terraform.tf @@ -0,0 +1,19 @@ +terraform { + required_version = "~> 1.7" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.74" + } + random = { + source = "hashicorp/random" + version = "~> 3.5" + } + } +} + +provider "azurerm" { + features {} +} + + diff --git a/examples/encrypted-disk/variables.tf b/examples/encrypted-disk/variables.tf new file mode 100644 index 0000000..1318944 --- /dev/null +++ b/examples/encrypted-disk/variables.tf @@ -0,0 +1,9 @@ +variable "enable_telemetry" { + type = bool + default = true + description = < +# Default example + +This deploys a disk with a private endpoint. + +```hcl +# This allows us to randomize the region for the resource group. +module "regions" { + source = "Azure/regions/azurerm" + version = ">= 0.3.0" +} + +# This allows us to randomize the region for the resource group. +resource "random_integer" "region_index" { + max = length(module.regions.regions) - 1 + min = 0 +} + +# This ensures we have unique CAF compliant names for our resources. +module "naming" { + source = "Azure/naming/azurerm" + version = "0.3.0" +} + +# This is required for resource modules +resource "azurerm_resource_group" "this" { + location = module.regions.regions[random_integer.region_index.result].name + name = module.naming.resource_group.name_unique + tags = local.tags +} + +# A vnet is required for the private endpoint. +resource "azurerm_virtual_network" "this" { + address_space = ["192.168.0.0/24"] + location = azurerm_resource_group.this.location + name = module.naming.virtual_network.name_unique + resource_group_name = azurerm_resource_group.this.name + tags = local.tags +} + +resource "azurerm_subnet" "this" { + address_prefixes = ["192.168.0.0/24"] + name = module.naming.subnet.name_unique + resource_group_name = azurerm_resource_group.this.name + virtual_network_name = azurerm_virtual_network.this.name +} + +resource "azurerm_private_dns_zone" "this" { + name = "privatelink.blob.core.windows.net" + resource_group_name = azurerm_resource_group.this.name + tags = local.tags +} + +resource "azurerm_disk_access" "this" { + location = azurerm_resource_group.this.location + name = replace(azurerm_resource_group.this.name, "rg", "da") // Naming module does not support disk access + resource_group_name = azurerm_resource_group.this.name + tags = local.tags +} + +# This is the module call +module "disk" { + source = "../../" + # source = "Azure/avm-res-compute-disk/azurerm" + # ... + location = azurerm_resource_group.this.location + name = module.naming.managed_disk.name_unique + resource_group_name = azurerm_resource_group.this.name + + enable_telemetry = var.enable_telemetry # see variables.tf + network_access_policy = "AllowPrivate" + disk_access_id = azurerm_disk_access.this.id + create_option = "Empty" + storage_account_type = "PremiumV2_LRS" + disk_size_gb = 1024 + tags = local.tags + private_endpoints = { + pe_endpoint = { + name = module.naming.private_endpoint.name_unique + private_dns_zone_resource_ids = [azurerm_private_dns_zone.this.id] + private_service_connection_name = "pse-${module.naming.private_endpoint.name_unique}" + subnet_resource_id = azurerm_subnet.this.id + } + } +} +``` + + +## Requirements + +The following requirements are needed by this module: + +- [terraform](#requirement\_terraform) (~> 1.7) + +- [azurerm](#requirement\_azurerm) (~> 3.74) + +- [random](#requirement\_random) (~> 3.5) + +## Providers + +The following providers are used by this module: + +- [azurerm](#provider\_azurerm) (~> 3.74) + +- [random](#provider\_random) (~> 3.5) + +## Resources + +The following resources are used by this module: + +- [azurerm_disk_access.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/disk_access) (resource) +- [azurerm_private_dns_zone.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/private_dns_zone) (resource) +- [azurerm_resource_group.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/resource_group) (resource) +- [azurerm_subnet.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/subnet) (resource) +- [azurerm_virtual_network.this](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network) (resource) +- [random_integer.region_index](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/integer) (resource) + + +## Required Inputs + +No required inputs. + +## Optional Inputs + +The following input variables are optional (have default values): + +### [enable\_telemetry](#input\_enable\_telemetry) + +Description: This variable controls whether or not telemetry is enabled for the module. +For more information see https://aka.ms/avm/telemetryinfo. +If it is set to false, then no telemetry will be collected. + +Type: `bool` + +Default: `true` + +## Outputs + +The following outputs are exported: + +### [location](#output\_location) + +Description: The deployment region. + +### [resource](#output\_resource) + +Description: This is the full output for the resource. + +### [resource\_group\_name](#output\_resource\_group\_name) + +Description: The name of the Resource Group. + +## Modules + +The following Modules are called: + +### [disk](#module\_disk) + +Source: ../../ + +Version: + +### [naming](#module\_naming) + +Source: Azure/naming/azurerm + +Version: 0.3.0 + +### [regions](#module\_regions) + +Source: Azure/regions/azurerm + +Version: >= 0.3.0 + + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. + \ No newline at end of file diff --git a/examples/private-endpoint/_footer.md b/examples/private-endpoint/_footer.md new file mode 100644 index 0000000..bc56bcb --- /dev/null +++ b/examples/private-endpoint/_footer.md @@ -0,0 +1,4 @@ + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/examples/private-endpoint/_header.md b/examples/private-endpoint/_header.md new file mode 100644 index 0000000..b5a16a3 --- /dev/null +++ b/examples/private-endpoint/_header.md @@ -0,0 +1,3 @@ +# Default example + +This deploys a disk with a private endpoint. diff --git a/examples/private-endpoint/locals.tf b/examples/private-endpoint/locals.tf new file mode 100644 index 0000000..c0908ac --- /dev/null +++ b/examples/private-endpoint/locals.tf @@ -0,0 +1,5 @@ +locals { + tags = { + scenario = "Disk Private Endpoint AVM Sample" + } +} \ No newline at end of file diff --git a/examples/private-endpoint/main.tf b/examples/private-endpoint/main.tf new file mode 100644 index 0000000..de646b2 --- /dev/null +++ b/examples/private-endpoint/main.tf @@ -0,0 +1,79 @@ +# This allows us to randomize the region for the resource group. +module "regions" { + source = "Azure/regions/azurerm" + version = ">= 0.3.0" +} + +# This allows us to randomize the region for the resource group. +resource "random_integer" "region_index" { + max = length(module.regions.regions) - 1 + min = 0 +} + +# This ensures we have unique CAF compliant names for our resources. +module "naming" { + source = "Azure/naming/azurerm" + version = "0.3.0" +} + +# This is required for resource modules +resource "azurerm_resource_group" "this" { + location = module.regions.regions[random_integer.region_index.result].name + name = module.naming.resource_group.name_unique + tags = local.tags +} + +# A vnet is required for the private endpoint. +resource "azurerm_virtual_network" "this" { + address_space = ["192.168.0.0/24"] + location = azurerm_resource_group.this.location + name = module.naming.virtual_network.name_unique + resource_group_name = azurerm_resource_group.this.name + tags = local.tags +} + +resource "azurerm_subnet" "this" { + address_prefixes = ["192.168.0.0/24"] + name = module.naming.subnet.name_unique + resource_group_name = azurerm_resource_group.this.name + virtual_network_name = azurerm_virtual_network.this.name +} + +resource "azurerm_private_dns_zone" "this" { + name = "privatelink.blob.core.windows.net" + resource_group_name = azurerm_resource_group.this.name + tags = local.tags +} + +resource "azurerm_disk_access" "this" { + location = azurerm_resource_group.this.location + name = replace(azurerm_resource_group.this.name, "rg", "da") // Naming module does not support disk access + resource_group_name = azurerm_resource_group.this.name + tags = local.tags +} + +# This is the module call +module "disk" { + source = "../../" + # source = "Azure/avm-res-compute-disk/azurerm" + # ... + location = azurerm_resource_group.this.location + name = module.naming.managed_disk.name_unique + resource_group_name = azurerm_resource_group.this.name + + enable_telemetry = var.enable_telemetry # see variables.tf + network_access_policy = "AllowPrivate" + disk_access_id = azurerm_disk_access.this.id + create_option = "Empty" + storage_account_type = "PremiumV2_LRS" + disk_size_gb = 1024 + tags = local.tags + private_endpoints = { + pe_endpoint = { + name = module.naming.private_endpoint.name_unique + private_dns_zone_resource_ids = [azurerm_private_dns_zone.this.id] + private_service_connection_name = "pse-${module.naming.private_endpoint.name_unique}" + subnet_resource_id = azurerm_subnet.this.id + } + } +} diff --git a/examples/private-endpoint/outputs.tf b/examples/private-endpoint/outputs.tf new file mode 100644 index 0000000..d204d79 --- /dev/null +++ b/examples/private-endpoint/outputs.tf @@ -0,0 +1,14 @@ +output "location" { + description = "The deployment region." + value = module.disk.location +} + +output "resource" { + description = "This is the full output for the resource." + value = module.disk.resource +} + +output "resource_group_name" { + description = "The name of the Resource Group." + value = module.disk.resource_group_name +} diff --git a/examples/private-endpoint/terraform.tf b/examples/private-endpoint/terraform.tf new file mode 100644 index 0000000..8dc4e9e --- /dev/null +++ b/examples/private-endpoint/terraform.tf @@ -0,0 +1,19 @@ +terraform { + required_version = "~> 1.7" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.74" + } + random = { + source = "hashicorp/random" + version = "~> 3.5" + } + } +} + +provider "azurerm" { + features {} +} + + diff --git a/examples/private-endpoint/variables.tf b/examples/private-endpoint/variables.tf new file mode 100644 index 0000000..1318944 --- /dev/null +++ b/examples/private-endpoint/variables.tf @@ -0,0 +1,9 @@ +variable "enable_telemetry" { + type = bool + default = true + description = < 0) ? { - this = { - type = var.managed_identities.system_assigned && length(var.managed_identities.user_assigned_resource_ids) > 0 ? "SystemAssigned, UserAssigned" : length(var.managed_identities.user_assigned_resource_ids) > 0 ? "UserAssigned" : "SystemAssigned" - user_assigned_resource_ids = var.managed_identities.user_assigned_resource_ids - } - } : {} - system_assigned = var.managed_identities.system_assigned ? { - this = { - type = "SystemAssigned" - } - } : {} - user_assigned = length(var.managed_identities.user_assigned_resource_ids) > 0 ? { - this = { - type = "UserAssigned" - user_assigned_resource_ids = var.managed_identities.user_assigned_resource_ids - } - } : {} - } - # Private endpoint application security group associations. # We merge the nested maps from private endpoints and application security group associations into a single map. private_endpoint_application_security_group_associations = { for assoc in flatten([ @@ -32,7 +11,6 @@ locals { } ] ]) : "${assoc.pe_key}-${assoc.asg_key}" => assoc } - role_definition_resource_substring = "/providers/Microsoft.Authorization/roleDefinitions" - } + diff --git a/main.privateendpoint.tf b/main.privateendpoint.tf index 53e8b71..13fbdfa 100644 --- a/main.privateendpoint.tf +++ b/main.privateendpoint.tf @@ -1,9 +1,9 @@ -# TODO remove this code & var.private_endpoints if private link is not support. Note it must be included in this module if it is supported. +# The PE resource when we are managing the private_dns_zone_group block: resource "azurerm_private_endpoint" "this_managed_dns_zone_groups" { - for_each = var.private_endpoints + for_each = { for k, v in var.private_endpoints : k => v if var.private_endpoints_manage_dns_zone_group } location = each.value.location != null ? each.value.location : var.location - name = each.value.name != null ? each.value.name : "pe-${var.name}" + name = each.value.name != null ? each.value.name : "pep-${var.name}" resource_group_name = each.value.resource_group_name != null ? each.value.resource_group_name : var.resource_group_name subnet_id = each.value.subnet_resource_id custom_network_interface_name = each.value.network_interface_name @@ -12,8 +12,8 @@ resource "azurerm_private_endpoint" "this_managed_dns_zone_groups" { private_service_connection { is_manual_connection = false name = each.value.private_service_connection_name != null ? each.value.private_service_connection_name : "pse-${var.name}" - private_connection_resource_id = azurerm_resource_group.TODO.id # TODO: Replace this dummy resource azurerm_resource_group.TODO with your module resource - subresource_names = ["TODO subresource name, see https://learn.microsoft.com/en-us/azure/private-link/private-endpoint-overview#private-link-resource"] + private_connection_resource_id = var.disk_access_id + subresource_names = ["disks"] # map to each.value.subresource_name if there are multiple services. } dynamic "ip_configuration" { for_each = each.value.ip_configurations @@ -21,8 +21,8 @@ resource "azurerm_private_endpoint" "this_managed_dns_zone_groups" { content { name = ip_configuration.value.name private_ip_address = ip_configuration.value.private_ip_address - member_name = "TODO subresource name" - subresource_name = "TODO subresource name" + member_name = "disks" # map to each.value.subresource_name if there are multiple services. + subresource_name = "disks" # map to each.value.subresource_name if there are multiple services. } } dynamic "private_dns_zone_group" { @@ -35,14 +35,12 @@ resource "azurerm_private_endpoint" "this_managed_dns_zone_groups" { } } -# The PE resource when we are managing **not** the private_dns_zone_group block -# An example use case is customers using Azure Policy to create private DNS zones -# e.g. +# The PE resource when we are managing **not** the private_dns_zone_group block: resource "azurerm_private_endpoint" "this_unmanaged_dns_zone_groups" { for_each = { for k, v in var.private_endpoints : k => v if !var.private_endpoints_manage_dns_zone_group } location = each.value.location != null ? each.value.location : var.location - name = each.value.name != null ? each.value.name : "pe-${var.name}" + name = each.value.name != null ? each.value.name : "pep-${var.name}" resource_group_name = each.value.resource_group_name != null ? each.value.resource_group_name : var.resource_group_name subnet_id = each.value.subnet_resource_id custom_network_interface_name = each.value.network_interface_name @@ -51,8 +49,8 @@ resource "azurerm_private_endpoint" "this_unmanaged_dns_zone_groups" { private_service_connection { is_manual_connection = false name = each.value.private_service_connection_name != null ? each.value.private_service_connection_name : "pse-${var.name}" - private_connection_resource_id = azurerm_resource_group.TODO.id # TODO: Replace this dummy resource azurerm_resource_group.TODO with your module resource - subresource_names = ["TODO subresource name, see https://learn.microsoft.com/en-us/azure/private-link/private-endpoint-overview#private-link-resource"] + private_connection_resource_id = var.disk_access_id + subresource_names = ["disks"] # map to each.value.subresource_name if there are multiple services. } dynamic "ip_configuration" { for_each = each.value.ip_configurations @@ -60,8 +58,8 @@ resource "azurerm_private_endpoint" "this_unmanaged_dns_zone_groups" { content { name = ip_configuration.value.name private_ip_address = ip_configuration.value.private_ip_address - member_name = "TODO subresource name" - subresource_name = "TODO subresource name" + member_name = "disks" # map to each.value.subresource_name if there are multiple services. + subresource_name = "disks" # map to each.value.subresource_name if there are multiple services. } } @@ -74,5 +72,6 @@ resource "azurerm_private_endpoint_application_security_group_association" "this for_each = local.private_endpoint_application_security_group_associations application_security_group_id = each.value.asg_resource_id - private_endpoint_id = var.private_endpoints_manage_dns_zone_group ? azurerm_private_endpoint.this_managed_dns_zone_groups[each.value.pe_key].id : azurerm_private_endpoint.this_unmanaged_dns_zone_groups[each.value.pe_key].id + private_endpoint_id = azurerm_private_endpoint.this_managed_dns_zone_groups[each.value.pe_key].id } + diff --git a/main.tf b/main.tf index 1e1dbb3..7316a37 100644 --- a/main.tf +++ b/main.tf @@ -1,17 +1,10 @@ -# TODO: Replace this dummy resource azurerm_resource_group.TODO with your module resource -resource "azurerm_resource_group" "TODO" { - location = var.location - name = var.name # calling code must supply the name - tags = var.tags -} - # required AVM resources interfaces resource "azurerm_management_lock" "this" { count = var.lock != null ? 1 : 0 lock_level = var.lock.kind name = coalesce(var.lock.name, "lock-${var.lock.kind}") - scope = azurerm_MY_RESOURCE.this.id + scope = azurerm_managed_disk.this.id notes = var.lock.kind == "CanNotDelete" ? "Cannot delete the resource or its child resources." : "Cannot delete or modify the resource or its child resources." } @@ -19,7 +12,7 @@ resource "azurerm_role_assignment" "this" { for_each = var.role_assignments principal_id = each.value.principal_id - scope = azurerm_resource_group.TODO.id # TODO: Replace this dummy resource azurerm_resource_group.TODO with your module resource + scope = azurerm_managed_disk.this.id condition = each.value.condition condition_version = each.value.condition_version delegated_managed_identity_resource_id = each.value.delegated_managed_identity_resource_id @@ -27,3 +20,65 @@ resource "azurerm_role_assignment" "this" { role_definition_name = strcontains(lower(each.value.role_definition_id_or_name), lower(local.role_definition_resource_substring)) ? null : each.value.role_definition_id_or_name skip_service_principal_aad_check = each.value.skip_service_principal_aad_check } + +data "azurerm_client_config" "current" {} + +resource "azurerm_managed_disk" "this" { + create_option = var.create_option + location = var.location + name = var.name + resource_group_name = var.resource_group_name + storage_account_type = var.storage_account_type + disk_access_id = var.disk_access_id + disk_encryption_set_id = var.disk_encryption_set_id + disk_iops_read_only = var.disk_iops_read_only + disk_iops_read_write = var.disk_iops_read_write + disk_mbps_read_only = var.disk_mbps_read_only + disk_mbps_read_write = var.disk_mbps_read_write + disk_size_gb = var.disk_size_gb + edge_zone = var.edge_zone + gallery_image_reference_id = var.gallery_image_reference_id + hyper_v_generation = var.hyper_v_generation + image_reference_id = var.image_reference_id + logical_sector_size = var.logical_sector_size + max_shares = var.max_shares + network_access_policy = var.network_access_policy + on_demand_bursting_enabled = var.on_demand_bursting_enabled + optimized_frequent_attach_enabled = var.optimized_frequent_attach_enabled + os_type = var.os_type + performance_plus_enabled = var.performance_plus_enabled + public_network_access_enabled = var.public_network_access_enabled + secure_vm_disk_encryption_set_id = var.secure_vm_disk_encryption_set_id + security_type = var.security_type + source_resource_id = var.source_resource_id + source_uri = var.source_uri + storage_account_id = var.storage_account_id + tags = var.tags + tier = var.tier + trusted_launch_enabled = var.trusted_launch_enabled + upload_size_bytes = var.upload_size_bytes + zone = var.zone + + dynamic "encryption_settings" { + for_each = var.encryption_settings == null ? [] : [var.encryption_settings] + content { + enabled = encryption_settings.value.enabled + + dynamic "disk_encryption_key" { + for_each = encryption_settings.value.disk_encryption_key == null ? [] : [encryption_settings.value.disk_encryption_key] + content { + secret_url = disk_encryption_key.value.secret_url + source_vault_id = disk_encryption_key.value.source_vault_id + } + } + dynamic "key_encryption_key" { + for_each = encryption_settings.value.key_encryption_key == null ? [] : [encryption_settings.value.key_encryption_key] + content { + key_url = key_encryption_key.value.key_url + source_vault_id = key_encryption_key.value.source_vault_id + } + } + } + } +} + diff --git a/outputs.tf b/outputs.tf index 5e93e10..27e77cd 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,7 +1,13 @@ +output "location" { + description = "The deployment region." + value = var.location +} + +# In your output you need to select the correct resource based on the value of var.private_endpoints_manage_dns_zone_group: output "private_endpoints" { description = <