From 9c9811cf23ab77c45acbff82fffd3bfc6113af49 Mon Sep 17 00:00:00 2001 From: terrymandin Date: Wed, 1 May 2024 08:34:07 -0600 Subject: [PATCH 01/13] Core functionality --- examples/default/main.tf | 7 +- main.privateendpoint.tf | 17 ++- main.tf | 68 +++++++++++- outputs.tf | 2 +- variables.tf | 224 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 297 insertions(+), 21 deletions(-) diff --git a/examples/default/main.tf b/examples/default/main.tf index 38cdd38..53bec19 100644 --- a/examples/default/main.tf +++ b/examples/default/main.tf @@ -49,11 +49,14 @@ resource "azurerm_resource_group" "this" { # with a data source. module "test" { 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 + create_option = "Empty" + storage_account_type = "Premium_LRS" + disk_size_gb = 1024 } diff --git a/main.privateendpoint.tf b/main.privateendpoint.tf index 53e8b71..5e44611 100644 --- a/main.privateendpoint.tf +++ b/main.privateendpoint.tf @@ -1,4 +1,3 @@ -# 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. resource "azurerm_private_endpoint" "this_managed_dns_zone_groups" { for_each = var.private_endpoints @@ -12,8 +11,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 = azurerm_managed_disk.this.id + subresource_names = ["managed disk"] } dynamic "ip_configuration" { for_each = each.value.ip_configurations @@ -21,8 +20,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 = "managed disk" + subresource_name = "managed disk" } } dynamic "private_dns_zone_group" { @@ -51,8 +50,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 = azurerm_managed_disk.this.id + subresource_names = ["managed disk"] } dynamic "ip_configuration" { for_each = each.value.ip_configurations @@ -60,8 +59,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 = "managed disk" + subresource_name = "managed disk" } } diff --git a/main.tf b/main.tf index 1e1dbb3..c6d4347 100644 --- a/main.tf +++ b/main.tf @@ -1,5 +1,4 @@ -# TODO: Replace this dummy resource azurerm_resource_group.TODO with your module resource -resource "azurerm_resource_group" "TODO" { +resource "azurerm_resource_group" "this" { location = var.location name = var.name # calling code must supply the name tags = var.tags @@ -11,7 +10,7 @@ resource "azurerm_management_lock" "this" { 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 +18,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 +26,64 @@ 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 } + + +resource "azurerm_managed_disk" "this" { + create_option = var.create_option + location = azurerm_resource_group.this.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..f3ec507 100644 --- a/outputs.tf +++ b/outputs.tf @@ -9,5 +9,5 @@ output "private_endpoints" { # https://azure.github.io/Azure-Verified-Modules/specs/terraform/#id-tffr2---category-outputs---additional-terraform-outputs output "resource" { description = "This is the full output for the resource." - value = azurerm_resource_group.TODO # TODO: Replace this dummy resource azurerm_resource_group.TODO with your module resource + value = azurerm_managed_disk.this } diff --git a/variables.tf b/variables.tf index 5722d2d..f02e199 100644 --- a/variables.tf +++ b/variables.tf @@ -1,12 +1,9 @@ variable "name" { type = string description = "The name of the this resource." - validation { - condition = can(regex("TODO", var.name)) - error_message = "The name must be TODO." # TODO remove the example below once complete: - #condition = can(regex("^[a-z0-9]{5,50}$", var.name)) - #error_message = "The name must be between 5 and 50 characters long and can only contain lowercase letters and numbers." + error_message = "The name must begin with a letter or number, end with a letter, number or underscore, and may contain only letters, numbers, underscores, periods, or hyphens, and must be less than 80 characters." + condition = can(regex("^[A-Za-z0-9][A-Za-z0-9_.-]{0,78}[A-Za-z0-9_]$", var.name)) } } @@ -232,3 +229,220 @@ variable "tags" { default = null description = "(Optional) Tags of the resource." } + + +variable "create_option" { + type = string + description = "(Required) The method to use when creating the managed disk. Changing this forces a new resource to be created. Possible values include: * `Import`" + nullable = false + validation { + condition = contains(["Attach", "Copy", "CopyStart", "Empty", "FromImage", "Import", "ImportSecure", "Restore", "Upload", "UploadPreparedSecure"], var.create_option) + error_message = "The create option must be one of: 'Attach', 'Copy', CopyStart', 'Empty', 'FromImage', 'Import', 'ImportSecure', 'Restore', 'Upload', 'UploadPreparedSecure'." + } +} + +variable "storage_account_type" { + type = string + 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`." + nullable = false + validation { + condition = can(regex("^(Standard_LRS|StandardSSD_ZRS|Premium_LRS|PremiumV2_LRS|Premium_ZRS|StandardSSD_LRS|UltraSSD_LRS)$", var.storage_account_type)) + error_message = "The storage account type must be one of: 'Standard_LRS', 'StandardSSD_ZRS', 'Premium_LRS', 'PremiumV2_LRS', 'Premium_ZRS', 'StandardSSD_LRS', 'UltraSSD_LRS'." + } +} + +variable "disk_access_id" { + type = string + default = null + description = "(Optional) The ID of the disk access resource for using private endpoints on disks." +} + +variable "disk_encryption_set_id" { + type = string + default = null + 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`." +} + +variable "disk_iops_read_only" { + type = number + default = null + 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." +} + +variable "disk_iops_read_write" { + type = number + default = null + 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." +} + +variable "disk_mbps_read_only" { + type = number + default = null + 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." +} + +variable "disk_mbps_read_write" { + type = number + default = null + description = "(Optional) The bandwidth allowed for this disk; only settable for UltraSSD disks and PremiumV2 disks. MBps means millions of bytes per second." +} + +variable "disk_size_gb" { + type = number + default = null + 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." +} + +variable "edge_zone" { + type = string + default = null + 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." +} + +variable "encryption_settings" { + type = 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 + description = <<-EOT + - `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. +EOT +} + +variable "gallery_image_reference_id" { + type = string + default = null + 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." +} + +variable "hyper_v_generation" { + type = string + default = null + 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." +} + +variable "image_reference_id" { + type = string + default = null + 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." +} + +variable "logical_sector_size" { + type = number + default = null + description = "(Optional) Logical Sector Size. Possible values are: `512` and `4096`. Defaults to `4096`. Changing this forces a new resource to be created." +} + +variable "max_shares" { + type = number + default = null + 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." +} + +variable "network_access_policy" { + type = string + default = null + description = "(Optional) Policy for accessing the disk via network. Allowed values are `AllowAll`, `AllowPrivate`, and `DenyAll`." +} + +variable "on_demand_bursting_enabled" { + type = bool + default = null + description = "(Optional) Specifies if On-Demand Bursting is enabled for the Managed Disk." +} + +variable "optimized_frequent_attach_enabled" { + type = bool + default = null + 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`." +} + +variable "os_type" { + type = string + default = null + 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`." +} + +variable "performance_plus_enabled" { + type = bool + default = null + description = "(Optional) Specifies whether Performance Plus is enabled for this Managed Disk. Defaults to `false`. Changing this forces a new resource to be created." +} + +variable "public_network_access_enabled" { + type = bool + default = null + description = "(Optional) Whether it is allowed to access the disk via public network. Defaults to `true`." +} + +variable "secure_vm_disk_encryption_set_id" { + type = string + default = null + 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." +} + +variable "security_type" { + type = string + default = null + 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." +} + +variable "source_resource_id" { + type = string + default = null + 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." +} + +variable "source_uri" { + type = string + default = null + 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." +} + +variable "storage_account_id" { + type = string + default = null + 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." +} + +variable "tier" { + type = string + default = null + 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." +} + +variable "trusted_launch_enabled" { + type = bool + default = null + description = "(Optional) Specifies if Trusted Launch is enabled for the Managed Disk. Changing this forces a new resource to be created." +} + +variable "upload_size_bytes" { + type = number + default = null + 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." +} + +variable "zone" { + type = string + default = null + description = "(Optional) Specifies the Availability Zone in which this Managed Disk should be located. Changing this property forces a new resource to be created." +} From b0a91af8b682f088218afb59b124626ce4fb4059 Mon Sep 17 00:00:00 2001 From: terrymandin Date: Wed, 1 May 2024 09:19:12 -0600 Subject: [PATCH 02/13] Add RBAC example --- examples/default/main.tf | 11 +++++++++++ main.tf | 10 ++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/examples/default/main.tf b/examples/default/main.tf index 53bec19..3822ab6 100644 --- a/examples/default/main.tf +++ b/examples/default/main.tf @@ -43,6 +43,8 @@ resource "azurerm_resource_group" "this" { name = module.naming.resource_group.name_unique } +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 @@ -59,4 +61,13 @@ module "test" { create_option = "Empty" storage_account_type = "Premium_LRS" disk_size_gb = 1024 + + // 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/main.tf b/main.tf index c6d4347..d90dd47 100644 --- a/main.tf +++ b/main.tf @@ -1,9 +1,3 @@ -resource "azurerm_resource_group" "this" { - 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 @@ -16,7 +10,6 @@ resource "azurerm_management_lock" "this" { resource "azurerm_role_assignment" "this" { for_each = var.role_assignments - principal_id = each.value.principal_id scope = azurerm_managed_disk.this.id condition = each.value.condition @@ -27,10 +20,11 @@ resource "azurerm_role_assignment" "this" { 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 = azurerm_resource_group.this.location + location = var.location name = var.name resource_group_name = var.resource_group_name storage_account_type = var.storage_account_type From 16dee8414350e99c166f1e4017aa12e787e214c4 Mon Sep 17 00:00:00 2001 From: terrymandin Date: Wed, 1 May 2024 09:43:11 -0600 Subject: [PATCH 03/13] Diagnostic Settings Example --- examples/default/main.tf | 21 +--- examples/default/terraform.tf | 19 +++ examples/diagnostic-settings/README.md | 143 ++++++++++++++++++++++ examples/diagnostic-settings/_footer.md | 4 + examples/diagnostic-settings/_header.md | 3 + examples/diagnostic-settings/locals.tf | 0 examples/diagnostic-settings/main.tf | 47 +++++++ examples/diagnostic-settings/outputs.tf | 0 examples/diagnostic-settings/terraform.tf | 19 +++ examples/diagnostic-settings/variables.tf | 9 ++ examples/private-enpoint/README.md | 143 ++++++++++++++++++++++ examples/private-enpoint/_footer.md | 4 + examples/private-enpoint/_header.md | 3 + examples/private-enpoint/locals.tf | 0 examples/private-enpoint/main.tf | 0 examples/private-enpoint/outputs.tf | 0 examples/private-enpoint/terraform.tf | 19 +++ 17 files changed, 414 insertions(+), 20 deletions(-) create mode 100644 examples/default/terraform.tf create mode 100644 examples/diagnostic-settings/README.md create mode 100644 examples/diagnostic-settings/_footer.md create mode 100644 examples/diagnostic-settings/_header.md create mode 100644 examples/diagnostic-settings/locals.tf create mode 100644 examples/diagnostic-settings/main.tf create mode 100644 examples/diagnostic-settings/outputs.tf create mode 100644 examples/diagnostic-settings/terraform.tf create mode 100644 examples/diagnostic-settings/variables.tf create mode 100644 examples/private-enpoint/README.md create mode 100644 examples/private-enpoint/_footer.md create mode 100644 examples/private-enpoint/_header.md create mode 100644 examples/private-enpoint/locals.tf create mode 100644 examples/private-enpoint/main.tf create mode 100644 examples/private-enpoint/outputs.tf create mode 100644 examples/private-enpoint/terraform.tf diff --git a/examples/default/main.tf b/examples/default/main.tf index 3822ab6..662a457 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" { @@ -49,7 +30,7 @@ data "azurerm_client_config" "current" {} # 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-res-compute-disk/azurerm" # ... diff --git a/examples/default/terraform.tf b/examples/default/terraform.tf new file mode 100644 index 0000000..0a62505 --- /dev/null +++ b/examples/default/terraform.tf @@ -0,0 +1,19 @@ +terraform { + required_version = "~> 1.6" + 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..1abcc3c --- /dev/null +++ b/examples/diagnostic-settings/README.md @@ -0,0 +1,143 @@ + +# Default example + +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" { + source = "Azure/regions/azurerm" + version = "~> 0.3" +} + +# This allows us to randomize the region for the resource group. +resource "random_integer" "region_index" { + max = length(module.regions.regions) - 1 + min = 0 +} +## End of section to provide a random Azure region for the resource group + +# This ensures we have unique CAF compliant names for our resources. +module "naming" { + source = "Azure/naming/azurerm" + version = "~> 0.3" +} + +# 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 +# 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" { + source = "../../" + # source = "Azure/avm--/azurerm" + # ... + location = azurerm_resource_group.this.location + name = "TODO" # TODO update with module.naming..name_unique + resource_group_name = azurerm_resource_group.this.name + + enable_telemetry = var.enable_telemetry # see variables.tf +} +``` + + +## Requirements + +The following requirements are needed by this module: + +- [terraform](#requirement\_terraform) (~> 1.5) + +- [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_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 . +If it is set to false, then no telemetry will be collected. + +Type: `bool` + +Default: `true` + +## Outputs + +No outputs. + +## Modules + +The following Modules are called: + +### [naming](#module\_naming) + +Source: Azure/naming/azurerm + +Version: ~> 0.3 + +### [regions](#module\_regions) + +Source: Azure/regions/azurerm + +Version: ~> 0.3 + +### [test](#module\_test) + +Source: ../../ + +Version: + + +## 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..9eb0b85 --- /dev/null +++ b/examples/diagnostic-settings/_header.md @@ -0,0 +1,3 @@ +# Default example + +This deploys the module in its simplest form. diff --git a/examples/diagnostic-settings/locals.tf b/examples/diagnostic-settings/locals.tf new file mode 100644 index 0000000..e69de29 diff --git a/examples/diagnostic-settings/main.tf b/examples/diagnostic-settings/main.tf new file mode 100644 index 0000000..9c78904 --- /dev/null +++ b/examples/diagnostic-settings/main.tf @@ -0,0 +1,47 @@ +# We need the tenant id for the key vault. +data "azurerm_client_config" "this" {} + +# 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 +} + +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 +} + +# 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 = "Premium_LRS" + disk_size_gb = 1024 +} \ 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..e69de29 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..4e20ee8 --- /dev/null +++ b/examples/diagnostic-settings/variables.tf @@ -0,0 +1,9 @@ +variable "enable_telemetry" { + type = bool + default = true + description = < +# Default example + +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" { + source = "Azure/regions/azurerm" + version = "~> 0.3" +} + +# This allows us to randomize the region for the resource group. +resource "random_integer" "region_index" { + max = length(module.regions.regions) - 1 + min = 0 +} +## End of section to provide a random Azure region for the resource group + +# This ensures we have unique CAF compliant names for our resources. +module "naming" { + source = "Azure/naming/azurerm" + version = "~> 0.3" +} + +# 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 +# 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" { + source = "../../" + # source = "Azure/avm--/azurerm" + # ... + location = azurerm_resource_group.this.location + name = "TODO" # TODO update with module.naming..name_unique + resource_group_name = azurerm_resource_group.this.name + + enable_telemetry = var.enable_telemetry # see variables.tf +} +``` + + +## Requirements + +The following requirements are needed by this module: + +- [terraform](#requirement\_terraform) (~> 1.5) + +- [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_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 . +If it is set to false, then no telemetry will be collected. + +Type: `bool` + +Default: `true` + +## Outputs + +No outputs. + +## Modules + +The following Modules are called: + +### [naming](#module\_naming) + +Source: Azure/naming/azurerm + +Version: ~> 0.3 + +### [regions](#module\_regions) + +Source: Azure/regions/azurerm + +Version: ~> 0.3 + +### [test](#module\_test) + +Source: ../../ + +Version: + + +## 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-enpoint/_footer.md b/examples/private-enpoint/_footer.md new file mode 100644 index 0000000..bc56bcb --- /dev/null +++ b/examples/private-enpoint/_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-enpoint/_header.md b/examples/private-enpoint/_header.md new file mode 100644 index 0000000..9eb0b85 --- /dev/null +++ b/examples/private-enpoint/_header.md @@ -0,0 +1,3 @@ +# Default example + +This deploys the module in its simplest form. diff --git a/examples/private-enpoint/locals.tf b/examples/private-enpoint/locals.tf new file mode 100644 index 0000000..e69de29 diff --git a/examples/private-enpoint/main.tf b/examples/private-enpoint/main.tf new file mode 100644 index 0000000..e69de29 diff --git a/examples/private-enpoint/outputs.tf b/examples/private-enpoint/outputs.tf new file mode 100644 index 0000000..e69de29 diff --git a/examples/private-enpoint/terraform.tf b/examples/private-enpoint/terraform.tf new file mode 100644 index 0000000..8dc4e9e --- /dev/null +++ b/examples/private-enpoint/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 {} +} + + From ff801dc63bc542817af2d0a16aa05f09bc1800f1 Mon Sep 17 00:00:00 2001 From: terrymandin Date: Wed, 1 May 2024 10:44:33 -0600 Subject: [PATCH 04/13] Removed Managed Identities and Private Endpoints --- examples/diagnostic-settings/main.tf | 3 - examples/{private-enpoint => max}/README.md | 0 examples/{private-enpoint => max}/_footer.md | 0 examples/{private-enpoint => max}/_header.md | 0 examples/{private-enpoint => max}/locals.tf | 0 examples/max/main.tf | 44 +++++++++++ examples/{private-enpoint => max}/outputs.tf | 0 .../{private-enpoint => max}/terraform.tf | 0 examples/max/variables.tf | 9 +++ examples/private-enpoint/main.tf | 0 locals.tf | 34 -------- main.privateendpoint.tf | 77 ------------------ outputs.tf | 7 -- variables.tf | 79 ------------------- 14 files changed, 53 insertions(+), 200 deletions(-) rename examples/{private-enpoint => max}/README.md (100%) rename examples/{private-enpoint => max}/_footer.md (100%) rename examples/{private-enpoint => max}/_header.md (100%) rename examples/{private-enpoint => max}/locals.tf (100%) create mode 100644 examples/max/main.tf rename examples/{private-enpoint => max}/outputs.tf (100%) rename examples/{private-enpoint => max}/terraform.tf (100%) create mode 100644 examples/max/variables.tf delete mode 100644 examples/private-enpoint/main.tf delete mode 100644 main.privateendpoint.tf diff --git a/examples/diagnostic-settings/main.tf b/examples/diagnostic-settings/main.tf index 9c78904..ce535fa 100644 --- a/examples/diagnostic-settings/main.tf +++ b/examples/diagnostic-settings/main.tf @@ -1,6 +1,3 @@ -# We need the tenant id for the key vault. -data "azurerm_client_config" "this" {} - # This allows us to randomize the region for the resource group. module "regions" { source = "Azure/regions/azurerm" diff --git a/examples/private-enpoint/README.md b/examples/max/README.md similarity index 100% rename from examples/private-enpoint/README.md rename to examples/max/README.md diff --git a/examples/private-enpoint/_footer.md b/examples/max/_footer.md similarity index 100% rename from examples/private-enpoint/_footer.md rename to examples/max/_footer.md diff --git a/examples/private-enpoint/_header.md b/examples/max/_header.md similarity index 100% rename from examples/private-enpoint/_header.md rename to examples/max/_header.md diff --git a/examples/private-enpoint/locals.tf b/examples/max/locals.tf similarity index 100% rename from examples/private-enpoint/locals.tf rename to examples/max/locals.tf diff --git a/examples/max/main.tf b/examples/max/main.tf new file mode 100644 index 0000000..ce535fa --- /dev/null +++ b/examples/max/main.tf @@ -0,0 +1,44 @@ +# 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 +} + +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 +} + +# 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 = "Premium_LRS" + disk_size_gb = 1024 +} \ No newline at end of file diff --git a/examples/private-enpoint/outputs.tf b/examples/max/outputs.tf similarity index 100% rename from examples/private-enpoint/outputs.tf rename to examples/max/outputs.tf diff --git a/examples/private-enpoint/terraform.tf b/examples/max/terraform.tf similarity index 100% rename from examples/private-enpoint/terraform.tf rename to examples/max/terraform.tf diff --git a/examples/max/variables.tf b/examples/max/variables.tf new file mode 100644 index 0000000..4e20ee8 --- /dev/null +++ b/examples/max/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([ - for pe_k, pe_v in var.private_endpoints : [ - for asg_k, asg_v in pe_v.application_security_group_associations : { - asg_key = asg_k - pe_key = pe_k - asg_resource_id = asg_v - } - ] - ]) : "${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 deleted file mode 100644 index 5e44611..0000000 --- a/main.privateendpoint.tf +++ /dev/null @@ -1,77 +0,0 @@ -resource "azurerm_private_endpoint" "this_managed_dns_zone_groups" { - for_each = var.private_endpoints - - location = each.value.location != null ? each.value.location : var.location - name = each.value.name != null ? each.value.name : "pe-${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 - tags = each.value.tags - - 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_managed_disk.this.id - subresource_names = ["managed disk"] - } - dynamic "ip_configuration" { - for_each = each.value.ip_configurations - - content { - name = ip_configuration.value.name - private_ip_address = ip_configuration.value.private_ip_address - member_name = "managed disk" - subresource_name = "managed disk" - } - } - dynamic "private_dns_zone_group" { - for_each = length(each.value.private_dns_zone_resource_ids) > 0 ? ["this"] : [] - - content { - name = each.value.private_dns_zone_group_name - private_dns_zone_ids = each.value.private_dns_zone_resource_ids - } - } -} - -# 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. -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}" - 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 - tags = each.value.tags - - 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_managed_disk.this.id - subresource_names = ["managed disk"] - } - dynamic "ip_configuration" { - for_each = each.value.ip_configurations - - content { - name = ip_configuration.value.name - private_ip_address = ip_configuration.value.private_ip_address - member_name = "managed disk" - subresource_name = "managed disk" - } - } - - lifecycle { - ignore_changes = [private_dns_zone_group] - } -} - -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 -} diff --git a/outputs.tf b/outputs.tf index f3ec507..644345d 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,10 +1,3 @@ -output "private_endpoints" { - description = < Date: Thu, 2 May 2024 14:28:52 -0600 Subject: [PATCH 05/13] Private Endpoints Example --- examples/max/main.tf | 34 +++++- examples/private-endpoint/README.md | 143 +++++++++++++++++++++++++ examples/private-endpoint/_footer.md | 4 + examples/private-endpoint/_header.md | 3 + examples/private-endpoint/locals.tf | 0 examples/private-endpoint/main.tf | 80 ++++++++++++++ examples/private-endpoint/outputs.tf | 0 examples/private-endpoint/terraform.tf | 19 ++++ examples/private-endpoint/variables.tf | 9 ++ locals.tf | 13 +++ main.privateendpoint.tf | 78 ++++++++++++++ outputs.tf | 8 ++ variables.tf | 58 ++++++++++ 13 files changed, 448 insertions(+), 1 deletion(-) create mode 100644 examples/private-endpoint/README.md create mode 100644 examples/private-endpoint/_footer.md create mode 100644 examples/private-endpoint/_header.md create mode 100644 examples/private-endpoint/locals.tf create mode 100644 examples/private-endpoint/main.tf create mode 100644 examples/private-endpoint/outputs.tf create mode 100644 examples/private-endpoint/terraform.tf create mode 100644 examples/private-endpoint/variables.tf create mode 100644 main.privateendpoint.tf diff --git a/examples/max/main.tf b/examples/max/main.tf index ce535fa..76ed0bf 100644 --- a/examples/max/main.tf +++ b/examples/max/main.tf @@ -41,4 +41,36 @@ module "disk" { create_option = "Empty" storage_account_type = "Premium_LRS" disk_size_gb = 1024 -} \ No newline at end of file +} + +/* + 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 +*/ \ No newline at end of file diff --git a/examples/private-endpoint/README.md b/examples/private-endpoint/README.md new file mode 100644 index 0000000..1abcc3c --- /dev/null +++ b/examples/private-endpoint/README.md @@ -0,0 +1,143 @@ + +# Default example + +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" { + source = "Azure/regions/azurerm" + version = "~> 0.3" +} + +# This allows us to randomize the region for the resource group. +resource "random_integer" "region_index" { + max = length(module.regions.regions) - 1 + min = 0 +} +## End of section to provide a random Azure region for the resource group + +# This ensures we have unique CAF compliant names for our resources. +module "naming" { + source = "Azure/naming/azurerm" + version = "~> 0.3" +} + +# 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 +# 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" { + source = "../../" + # source = "Azure/avm--/azurerm" + # ... + location = azurerm_resource_group.this.location + name = "TODO" # TODO update with module.naming..name_unique + resource_group_name = azurerm_resource_group.this.name + + enable_telemetry = var.enable_telemetry # see variables.tf +} +``` + + +## Requirements + +The following requirements are needed by this module: + +- [terraform](#requirement\_terraform) (~> 1.5) + +- [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_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 . +If it is set to false, then no telemetry will be collected. + +Type: `bool` + +Default: `true` + +## Outputs + +No outputs. + +## Modules + +The following Modules are called: + +### [naming](#module\_naming) + +Source: Azure/naming/azurerm + +Version: ~> 0.3 + +### [regions](#module\_regions) + +Source: Azure/regions/azurerm + +Version: ~> 0.3 + +### [test](#module\_test) + +Source: ../../ + +Version: + + +## 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..9eb0b85 --- /dev/null +++ b/examples/private-endpoint/_header.md @@ -0,0 +1,3 @@ +# Default example + +This deploys the module in its simplest form. diff --git a/examples/private-endpoint/locals.tf b/examples/private-endpoint/locals.tf new file mode 100644 index 0000000..e69de29 diff --git a/examples/private-endpoint/main.tf b/examples/private-endpoint/main.tf new file mode 100644 index 0000000..1b8ca9c --- /dev/null +++ b/examples/private-endpoint/main.tf @@ -0,0 +1,80 @@ +# 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 +} + +# 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 +} + +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 +} + +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 +} + +# 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 = "Premium_LRS" + disk_size_gb = 1024 + /*private_endpoints = { + primary = { + private_dns_zone_resource_ids = [azurerm_private_dns_zone.this.id] + subnet_resource_id = azurerm_subnet.this.id + } + }*/ + 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..e69de29 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..4e20ee8 --- /dev/null +++ b/examples/private-endpoint/variables.tf @@ -0,0 +1,9 @@ +variable "enable_telemetry" { + type = bool + default = true + description = < assoc } + role_definition_resource_substring = "/providers/Microsoft.Authorization/roleDefinitions" } + diff --git a/main.privateendpoint.tf b/main.privateendpoint.tf new file mode 100644 index 0000000..05fcbc0 --- /dev/null +++ b/main.privateendpoint.tf @@ -0,0 +1,78 @@ +# The PE resource when we are managing the private_dns_zone_group block: +resource "azurerm_private_endpoint" "this_managed_dns_zone_groups" { +for_each = { for k, v in var.private_endpoints : k => v if var.private_endpoints_manage_dns_zone_group } +name = each.value.name != null ? each.value.name : "pep-${var.name}" +location = each.value.location != null ? each.value.location : var.location +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 +tags = each.value.tags + +private_service_connection { + name = each.value.private_service_connection_name != null ? each.value.private_service_connection_name : "pse-${var.name}" + private_connection_resource_id = var.disk_access_id + is_manual_connection = false + subresource_names = ["disks"] # map to each.value.subresource_name if there are multiple services. +} + +dynamic "private_dns_zone_group" { + for_each = length(each.value.private_dns_zone_resource_ids) > 0 ? ["this"] : [] + + content { + name = each.value.private_dns_zone_group_name + private_dns_zone_ids = each.value.private_dns_zone_resource_ids + } +} + +dynamic "ip_configuration" { + for_each = each.value.ip_configurations + + content { + name = ip_configuration.value.name + subresource_name = "disks" # map to each.value.subresource_name if there are multiple services. + member_name = "disks" # map to each.value.subresource_name if there are multiple services. + private_ip_address = ip_configuration.value.private_ip_address + } +} +} + +# 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 } + + name = each.value.name != null ? each.value.name : "pep-${var.name}" + location = each.value.location != null ? each.value.location : var.location + 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 + tags = each.value.tags + + private_service_connection { + name = each.value.private_service_connection_name != null ? each.value.private_service_connection_name : "pse-${var.name}" + private_connection_resource_id = var.disk_access_id + is_manual_connection = false + subresource_names = ["disks"] # map to each.value.subresource_name if there are multiple services. + } + + dynamic "ip_configuration" { + for_each = each.value.ip_configurations + + content { + name = ip_configuration.value.name + subresource_name = "disks" # map to each.value.subresource_name if there are multiple services. + member_name = "disks" # map to each.value.subresource_name if there are multiple services. + private_ip_address = ip_configuration.value.private_ip_address + } + } + + lifecycle { + ignore_changes = [private_dns_zone_group] + } +} + +resource "azurerm_private_endpoint_application_security_group_association" "this" { +for_each = local.private_endpoint_application_security_group_associations +private_endpoint_id = azurerm_private_endpoint.this_managed_dns_zone_groups[each.value.pe_key].id +application_security_group_id = each.value.asg_resource_id +} + diff --git a/outputs.tf b/outputs.tf index 644345d..1e07f13 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,3 +1,11 @@ +# 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" { +value = var.private_endpoints_manage_dns_zone_group ? azurerm_private_endpoint.this_managed_dns_zone_groups : azurerm_private_endpoint.this_unmanaged_dns_zone_groups +description = < Date: Fri, 3 May 2024 12:35:05 -0600 Subject: [PATCH 06/13] Encrypted Disk Example --- examples/encrypted-disk/README copy.md | 143 ++++++++++++++++++++++++ examples/encrypted-disk/_footer.md | 4 + examples/encrypted-disk/_header.md | 3 + examples/encrypted-disk/dependencies.tf | 75 +++++++++++++ examples/encrypted-disk/locals.tf | 0 examples/encrypted-disk/main.tf | 71 ++++++++++++ examples/encrypted-disk/outputs.tf | 0 examples/encrypted-disk/terraform.tf | 19 ++++ examples/encrypted-disk/variables.tf | 9 ++ examples/max/dependencies.tf | 75 +++++++++++++ examples/max/main.tf | 11 +- 11 files changed, 402 insertions(+), 8 deletions(-) create mode 100644 examples/encrypted-disk/README copy.md create mode 100644 examples/encrypted-disk/_footer.md create mode 100644 examples/encrypted-disk/_header.md create mode 100644 examples/encrypted-disk/dependencies.tf create mode 100644 examples/encrypted-disk/locals.tf create mode 100644 examples/encrypted-disk/main.tf create mode 100644 examples/encrypted-disk/outputs.tf create mode 100644 examples/encrypted-disk/terraform.tf create mode 100644 examples/encrypted-disk/variables.tf create mode 100644 examples/max/dependencies.tf diff --git a/examples/encrypted-disk/README copy.md b/examples/encrypted-disk/README copy.md new file mode 100644 index 0000000..1abcc3c --- /dev/null +++ b/examples/encrypted-disk/README copy.md @@ -0,0 +1,143 @@ + +# Default example + +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" { + source = "Azure/regions/azurerm" + version = "~> 0.3" +} + +# This allows us to randomize the region for the resource group. +resource "random_integer" "region_index" { + max = length(module.regions.regions) - 1 + min = 0 +} +## End of section to provide a random Azure region for the resource group + +# This ensures we have unique CAF compliant names for our resources. +module "naming" { + source = "Azure/naming/azurerm" + version = "~> 0.3" +} + +# 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 +# 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" { + source = "../../" + # source = "Azure/avm--/azurerm" + # ... + location = azurerm_resource_group.this.location + name = "TODO" # TODO update with module.naming..name_unique + resource_group_name = azurerm_resource_group.this.name + + enable_telemetry = var.enable_telemetry # see variables.tf +} +``` + + +## Requirements + +The following requirements are needed by this module: + +- [terraform](#requirement\_terraform) (~> 1.5) + +- [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_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 . +If it is set to false, then no telemetry will be collected. + +Type: `bool` + +Default: `true` + +## Outputs + +No outputs. + +## Modules + +The following Modules are called: + +### [naming](#module\_naming) + +Source: Azure/naming/azurerm + +Version: ~> 0.3 + +### [regions](#module\_regions) + +Source: Azure/regions/azurerm + +Version: ~> 0.3 + +### [test](#module\_test) + +Source: ../../ + +Version: + + +## 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..9eb0b85 --- /dev/null +++ b/examples/encrypted-disk/_header.md @@ -0,0 +1,3 @@ +# Default example + +This deploys the module in its simplest form. diff --git a/examples/encrypted-disk/dependencies.tf b/examples/encrypted-disk/dependencies.tf new file mode 100644 index 0000000..938610d --- /dev/null +++ b/examples/encrypted-disk/dependencies.tf @@ -0,0 +1,75 @@ +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 +} + +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 = {} +} + +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 + + 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 + } + } + + wait_for_rbac_before_secret_operations = { + create = "120s" + } + + tags = {} +} + +resource "azurerm_disk_encryption_set" "this" { + location = azurerm_resource_group.this.location + name = module.naming.disk_encryption_set.name_unique + resource_group_name = azurerm_resource_group.this.name + identity { + type = "UserAssigned" + identity_ids = [azurerm_user_assigned_identity.this.id] + } + key_vault_key_id = module.key_vault.resource_keys["cmkfordisk"].id +} diff --git a/examples/encrypted-disk/locals.tf b/examples/encrypted-disk/locals.tf new file mode 100644 index 0000000..e69de29 diff --git a/examples/encrypted-disk/main.tf b/examples/encrypted-disk/main.tf new file mode 100644 index 0000000..942c9bd --- /dev/null +++ b/examples/encrypted-disk/main.tf @@ -0,0 +1,71 @@ +# 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" + // disk_access_id = azurerm_disk_access.this.id // Already tested + storage_account_type = "Premium_LRS" + disk_size_gb = 1024 + disk_encryption_set_id = azurerm_disk_encryption_set.this.id + //disk_iops_read_only = 120 +} + +/* + 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 +*/ \ No newline at end of file diff --git a/examples/encrypted-disk/outputs.tf b/examples/encrypted-disk/outputs.tf new file mode 100644 index 0000000..e69de29 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..4e20ee8 --- /dev/null +++ b/examples/encrypted-disk/variables.tf @@ -0,0 +1,9 @@ +variable "enable_telemetry" { + type = bool + default = true + description = < Date: Fri, 3 May 2024 15:32:53 -0600 Subject: [PATCH 07/13] Add tags --- examples/default/locals.tf | 5 + examples/default/main.tf | 11 +- examples/diagnostic-settings/locals.tf | 5 + examples/diagnostic-settings/main.tf | 9 ++ examples/encrypted-disk/dependencies.tf | 8 +- examples/encrypted-disk/locals.tf | 5 + examples/encrypted-disk/main.tf | 32 ------ examples/max/README.md | 143 ------------------------ examples/max/_footer.md | 4 - examples/max/_header.md | 3 - examples/max/dependencies.tf | 75 ------------- examples/max/locals.tf | 0 examples/max/main.tf | 71 ------------ examples/max/outputs.tf | 0 examples/max/terraform.tf | 19 ---- examples/max/variables.tf | 9 -- examples/private-endpoint/locals.tf | 5 + examples/private-endpoint/main.tf | 11 +- 18 files changed, 47 insertions(+), 368 deletions(-) create mode 100644 examples/default/locals.tf delete mode 100644 examples/max/README.md delete mode 100644 examples/max/_footer.md delete mode 100644 examples/max/_header.md delete mode 100644 examples/max/dependencies.tf delete mode 100644 examples/max/locals.tf delete mode 100644 examples/max/main.tf delete mode 100644 examples/max/outputs.tf delete mode 100644 examples/max/terraform.tf delete mode 100644 examples/max/variables.tf 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 662a457..223d510 100644 --- a/examples/default/main.tf +++ b/examples/default/main.tf @@ -22,14 +22,12 @@ 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 "disk" { source = "../../" # source = "Azure/avm-res-compute-disk/azurerm" @@ -42,6 +40,13 @@ module "disk" { create_option = "Empty" storage_account_type = "Premium_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 = { diff --git a/examples/diagnostic-settings/locals.tf b/examples/diagnostic-settings/locals.tf index e69de29..06cc9a9 100644 --- a/examples/diagnostic-settings/locals.tf +++ 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 index ce535fa..b019aaa 100644 --- a/examples/diagnostic-settings/main.tf +++ b/examples/diagnostic-settings/main.tf @@ -20,12 +20,14 @@ 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 } 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 @@ -41,4 +43,11 @@ module "disk" { create_option = "Empty" storage_account_type = "Premium_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/encrypted-disk/dependencies.tf b/examples/encrypted-disk/dependencies.tf index 938610d..f1f7f2e 100644 --- a/examples/encrypted-disk/dependencies.tf +++ b/examples/encrypted-disk/dependencies.tf @@ -2,6 +2,7 @@ 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" {} @@ -10,7 +11,7 @@ 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 = {} + tags = local.tags } module "key_vault" { @@ -21,6 +22,7 @@ module "key_vault" { 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" @@ -53,14 +55,13 @@ module "key_vault" { key_vault_id = module.key_vault.resource.id name = "cmkfordisk" key_size = 2048 + tags = local.tags } } wait_for_rbac_before_secret_operations = { create = "120s" } - - tags = {} } resource "azurerm_disk_encryption_set" "this" { @@ -72,4 +73,5 @@ resource "azurerm_disk_encryption_set" "this" { identity_ids = [azurerm_user_assigned_identity.this.id] } key_vault_key_id = module.key_vault.resource_keys["cmkfordisk"].id + tags = local.tags } diff --git a/examples/encrypted-disk/locals.tf b/examples/encrypted-disk/locals.tf index e69de29..33fa1fa 100644 --- a/examples/encrypted-disk/locals.tf +++ 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 index 942c9bd..088fe88 100644 --- a/examples/encrypted-disk/main.tf +++ b/examples/encrypted-disk/main.tf @@ -33,39 +33,7 @@ module "disk" { enable_telemetry = var.enable_telemetry # see variables.tf create_option = "Empty" - // disk_access_id = azurerm_disk_access.this.id // Already tested storage_account_type = "Premium_LRS" disk_size_gb = 1024 disk_encryption_set_id = azurerm_disk_encryption_set.this.id - //disk_iops_read_only = 120 } - -/* - 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 -*/ \ No newline at end of file diff --git a/examples/max/README.md b/examples/max/README.md deleted file mode 100644 index 1abcc3c..0000000 --- a/examples/max/README.md +++ /dev/null @@ -1,143 +0,0 @@ - -# Default example - -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" { - source = "Azure/regions/azurerm" - version = "~> 0.3" -} - -# This allows us to randomize the region for the resource group. -resource "random_integer" "region_index" { - max = length(module.regions.regions) - 1 - min = 0 -} -## End of section to provide a random Azure region for the resource group - -# This ensures we have unique CAF compliant names for our resources. -module "naming" { - source = "Azure/naming/azurerm" - version = "~> 0.3" -} - -# 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 -# 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" { - source = "../../" - # source = "Azure/avm--/azurerm" - # ... - location = azurerm_resource_group.this.location - name = "TODO" # TODO update with module.naming..name_unique - resource_group_name = azurerm_resource_group.this.name - - enable_telemetry = var.enable_telemetry # see variables.tf -} -``` - - -## Requirements - -The following requirements are needed by this module: - -- [terraform](#requirement\_terraform) (~> 1.5) - -- [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_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 . -If it is set to false, then no telemetry will be collected. - -Type: `bool` - -Default: `true` - -## Outputs - -No outputs. - -## Modules - -The following Modules are called: - -### [naming](#module\_naming) - -Source: Azure/naming/azurerm - -Version: ~> 0.3 - -### [regions](#module\_regions) - -Source: Azure/regions/azurerm - -Version: ~> 0.3 - -### [test](#module\_test) - -Source: ../../ - -Version: - - -## 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/max/_footer.md b/examples/max/_footer.md deleted file mode 100644 index bc56bcb..0000000 --- a/examples/max/_footer.md +++ /dev/null @@ -1,4 +0,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. diff --git a/examples/max/_header.md b/examples/max/_header.md deleted file mode 100644 index 9eb0b85..0000000 --- a/examples/max/_header.md +++ /dev/null @@ -1,3 +0,0 @@ -# Default example - -This deploys the module in its simplest form. diff --git a/examples/max/dependencies.tf b/examples/max/dependencies.tf deleted file mode 100644 index 938610d..0000000 --- a/examples/max/dependencies.tf +++ /dev/null @@ -1,75 +0,0 @@ -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 -} - -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 = {} -} - -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 - - 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 - } - } - - wait_for_rbac_before_secret_operations = { - create = "120s" - } - - tags = {} -} - -resource "azurerm_disk_encryption_set" "this" { - location = azurerm_resource_group.this.location - name = module.naming.disk_encryption_set.name_unique - resource_group_name = azurerm_resource_group.this.name - identity { - type = "UserAssigned" - identity_ids = [azurerm_user_assigned_identity.this.id] - } - key_vault_key_id = module.key_vault.resource_keys["cmkfordisk"].id -} diff --git a/examples/max/locals.tf b/examples/max/locals.tf deleted file mode 100644 index e69de29..0000000 diff --git a/examples/max/main.tf b/examples/max/main.tf deleted file mode 100644 index 942c9bd..0000000 --- a/examples/max/main.tf +++ /dev/null @@ -1,71 +0,0 @@ -# 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" - // disk_access_id = azurerm_disk_access.this.id // Already tested - storage_account_type = "Premium_LRS" - disk_size_gb = 1024 - disk_encryption_set_id = azurerm_disk_encryption_set.this.id - //disk_iops_read_only = 120 -} - -/* - 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 -*/ \ No newline at end of file diff --git a/examples/max/outputs.tf b/examples/max/outputs.tf deleted file mode 100644 index e69de29..0000000 diff --git a/examples/max/terraform.tf b/examples/max/terraform.tf deleted file mode 100644 index 8dc4e9e..0000000 --- a/examples/max/terraform.tf +++ /dev/null @@ -1,19 +0,0 @@ -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/max/variables.tf b/examples/max/variables.tf deleted file mode 100644 index 4e20ee8..0000000 --- a/examples/max/variables.tf +++ /dev/null @@ -1,9 +0,0 @@ -variable "enable_telemetry" { - type = bool - default = true - description = < Date: Fri, 3 May 2024 16:21:05 -0600 Subject: [PATCH 08/13] Documentation, pre-commit --- _header.md | 13 ------------- examples/default/outputs.tf | 14 ++++++++++++++ examples/diagnostic-settings/_header.md | 2 +- examples/diagnostic-settings/outputs.tf | 14 ++++++++++++++ examples/encrypted-disk/_header.md | 2 +- examples/encrypted-disk/outputs.tf | 14 ++++++++++++++ examples/private-endpoint/_header.md | 2 +- examples/private-endpoint/outputs.tf | 14 ++++++++++++++ outputs.tf | 11 +++++++++++ 9 files changed, 70 insertions(+), 16 deletions(-) create mode 100644 examples/default/outputs.tf 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/outputs.tf b/examples/default/outputs.tf new file mode 100644 index 0000000..dd78112 --- /dev/null +++ b/examples/default/outputs.tf @@ -0,0 +1,14 @@ +output "location" { + description = "The deployment region." + value = module.disk.location +} + +output "resource_group_name" { + description = "The name of the Resource Group." + value = module.disk.resource_group_name +} + +output "resource" { + description = "This is the full output for the resource." + value = module.disk.resource +} \ No newline at end of file diff --git a/examples/diagnostic-settings/_header.md b/examples/diagnostic-settings/_header.md index 9eb0b85..9e22474 100644 --- a/examples/diagnostic-settings/_header.md +++ b/examples/diagnostic-settings/_header.md @@ -1,3 +1,3 @@ # Default example -This deploys the module in its simplest form. +This deploys the module with diagnostic settings enabled. diff --git a/examples/diagnostic-settings/outputs.tf b/examples/diagnostic-settings/outputs.tf index e69de29..dd78112 100644 --- a/examples/diagnostic-settings/outputs.tf +++ b/examples/diagnostic-settings/outputs.tf @@ -0,0 +1,14 @@ +output "location" { + description = "The deployment region." + value = module.disk.location +} + +output "resource_group_name" { + description = "The name of the Resource Group." + value = module.disk.resource_group_name +} + +output "resource" { + description = "This is the full output for the resource." + value = module.disk.resource +} \ No newline at end of file diff --git a/examples/encrypted-disk/_header.md b/examples/encrypted-disk/_header.md index 9eb0b85..a6274aa 100644 --- a/examples/encrypted-disk/_header.md +++ b/examples/encrypted-disk/_header.md @@ -1,3 +1,3 @@ # Default example -This deploys the module in its simplest form. +This example deploys an encrypted disk. diff --git a/examples/encrypted-disk/outputs.tf b/examples/encrypted-disk/outputs.tf index e69de29..dd78112 100644 --- a/examples/encrypted-disk/outputs.tf +++ b/examples/encrypted-disk/outputs.tf @@ -0,0 +1,14 @@ +output "location" { + description = "The deployment region." + value = module.disk.location +} + +output "resource_group_name" { + description = "The name of the Resource Group." + value = module.disk.resource_group_name +} + +output "resource" { + description = "This is the full output for the resource." + value = module.disk.resource +} \ No newline at end of file diff --git a/examples/private-endpoint/_header.md b/examples/private-endpoint/_header.md index 9eb0b85..b5a16a3 100644 --- a/examples/private-endpoint/_header.md +++ b/examples/private-endpoint/_header.md @@ -1,3 +1,3 @@ # Default example -This deploys the module in its simplest form. +This deploys a disk with a private endpoint. diff --git a/examples/private-endpoint/outputs.tf b/examples/private-endpoint/outputs.tf index e69de29..dd78112 100644 --- a/examples/private-endpoint/outputs.tf +++ b/examples/private-endpoint/outputs.tf @@ -0,0 +1,14 @@ +output "location" { + description = "The deployment region." + value = module.disk.location +} + +output "resource_group_name" { + description = "The name of the Resource Group." + value = module.disk.resource_group_name +} + +output "resource" { + description = "This is the full output for the resource." + value = module.disk.resource +} \ No newline at end of file diff --git a/outputs.tf b/outputs.tf index 1e07f13..9d0558d 100644 --- a/outputs.tf +++ b/outputs.tf @@ -1,3 +1,13 @@ +output "location" { + description = "The deployment region." + value = var.location +} + +output "resource_group_name" { + description = "The name of the Resource Group." + value = var.resource_group_name +} + # 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" { value = var.private_endpoints_manage_dns_zone_group ? azurerm_private_endpoint.this_managed_dns_zone_groups : azurerm_private_endpoint.this_unmanaged_dns_zone_groups @@ -12,3 +22,4 @@ output "resource" { description = "This is the full output for the resource." value = azurerm_managed_disk.this } + From 1c988df862447adbdb98b529128dfebe7e104a50 Mon Sep 17 00:00:00 2001 From: terrymandin Date: Mon, 6 May 2024 14:37:20 -0600 Subject: [PATCH 09/13] Change to Premium Storage V2 account --- examples/default/main.tf | 2 +- examples/diagnostic-settings/main.tf | 2 +- examples/encrypted-disk/main.tf | 2 +- examples/private-endpoint/main.tf | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/default/main.tf b/examples/default/main.tf index 223d510..0bf731b 100644 --- a/examples/default/main.tf +++ b/examples/default/main.tf @@ -38,7 +38,7 @@ module "disk" { enable_telemetry = var.enable_telemetry # see variables.tf create_option = "Empty" - storage_account_type = "Premium_LRS" + storage_account_type = "PremiumV2_LRS" disk_size_gb = 1024 tags = local.tags diff --git a/examples/diagnostic-settings/main.tf b/examples/diagnostic-settings/main.tf index b019aaa..1212c9b 100644 --- a/examples/diagnostic-settings/main.tf +++ b/examples/diagnostic-settings/main.tf @@ -41,7 +41,7 @@ module "disk" { enable_telemetry = var.enable_telemetry # see variables.tf create_option = "Empty" - storage_account_type = "Premium_LRS" + storage_account_type = "PremiumV2_LRS" disk_size_gb = 1024 tags = local.tags diagnostic_settings = { diff --git a/examples/encrypted-disk/main.tf b/examples/encrypted-disk/main.tf index 088fe88..ebffb30 100644 --- a/examples/encrypted-disk/main.tf +++ b/examples/encrypted-disk/main.tf @@ -33,7 +33,7 @@ module "disk" { enable_telemetry = var.enable_telemetry # see variables.tf create_option = "Empty" - storage_account_type = "Premium_LRS" + storage_account_type = "PremiumV2_LRS" disk_size_gb = 1024 disk_encryption_set_id = azurerm_disk_encryption_set.this.id } diff --git a/examples/private-endpoint/main.tf b/examples/private-endpoint/main.tf index d9cd141..bb6d872 100644 --- a/examples/private-endpoint/main.tf +++ b/examples/private-endpoint/main.tf @@ -65,7 +65,7 @@ module "disk" { network_access_policy = "AllowPrivate" disk_access_id = azurerm_disk_access.this.id create_option = "Empty" - storage_account_type = "Premium_LRS" + storage_account_type = "PremiumV2_LRS" disk_size_gb = 1024 tags = local.tags private_endpoints = { From d91f1fc9ffc22e248734558445fb687aea3e82fe Mon Sep 17 00:00:00 2001 From: terrymandin Date: Mon, 6 May 2024 14:46:36 -0600 Subject: [PATCH 10/13] avmfix --- examples/default/main.tf | 10 +- examples/default/outputs.tf | 10 +- locals.tf | 11 +- main.privateendpoint.tf | 103 +++++++------ main.tf | 3 +- outputs.tf | 13 +- variables.tf | 297 ++++++++++++++++++------------------ 7 files changed, 222 insertions(+), 225 deletions(-) diff --git a/examples/default/main.tf b/examples/default/main.tf index 0bf731b..8db8d1c 100644 --- a/examples/default/main.tf +++ b/examples/default/main.tf @@ -22,7 +22,7 @@ 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 + tags = local.tags } data "azurerm_client_config" "current" {} @@ -36,11 +36,11 @@ module "disk" { 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" + enable_telemetry = var.enable_telemetry # see variables.tf + create_option = "Empty" storage_account_type = "PremiumV2_LRS" - disk_size_gb = 1024 - tags = local.tags + disk_size_gb = 1024 + tags = local.tags # Uncomment the code below to implement a VMSS Lock #lock = { diff --git a/examples/default/outputs.tf b/examples/default/outputs.tf index dd78112..d204d79 100644 --- a/examples/default/outputs.tf +++ b/examples/default/outputs.tf @@ -3,12 +3,12 @@ output "location" { 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 } - -output "resource" { - description = "This is the full output for the resource." - value = module.disk.resource -} \ No newline at end of file diff --git a/locals.tf b/locals.tf index 71c4f89..445624a 100644 --- a/locals.tf +++ b/locals.tf @@ -3,15 +3,14 @@ locals { # 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([ - for pe_k, pe_v in var.private_endpoints : [ + for pe_k, pe_v in var.private_endpoints : [ for asg_k, asg_v in pe_v.application_security_group_associations : { - asg_key = asg_k - pe_key = pe_k - asg_resource_id = asg_v + asg_key = asg_k + pe_key = pe_k + asg_resource_id = asg_v } - ] + ] ]) : "${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 05fcbc0..13fbdfa 100644 --- a/main.privateendpoint.tf +++ b/main.privateendpoint.tf @@ -1,78 +1,77 @@ # The PE resource when we are managing the private_dns_zone_group block: resource "azurerm_private_endpoint" "this_managed_dns_zone_groups" { -for_each = { for k, v in var.private_endpoints : k => v if var.private_endpoints_manage_dns_zone_group } -name = each.value.name != null ? each.value.name : "pep-${var.name}" -location = each.value.location != null ? each.value.location : var.location -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 -tags = each.value.tags + for_each = { for k, v in var.private_endpoints : k => v if var.private_endpoints_manage_dns_zone_group } -private_service_connection { + location = each.value.location != null ? each.value.location : var.location + 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 + tags = each.value.tags + + 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 = var.disk_access_id - is_manual_connection = false subresource_names = ["disks"] # map to each.value.subresource_name if there are multiple services. -} - -dynamic "private_dns_zone_group" { - for_each = length(each.value.private_dns_zone_resource_ids) > 0 ? ["this"] : [] + } + dynamic "ip_configuration" { + for_each = each.value.ip_configurations content { - name = each.value.private_dns_zone_group_name - private_dns_zone_ids = each.value.private_dns_zone_resource_ids + name = ip_configuration.value.name + private_ip_address = ip_configuration.value.private_ip_address + 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 "ip_configuration" { - for_each = each.value.ip_configurations + } + dynamic "private_dns_zone_group" { + for_each = length(each.value.private_dns_zone_resource_ids) > 0 ? ["this"] : [] content { - name = ip_configuration.value.name - subresource_name = "disks" # map to each.value.subresource_name if there are multiple services. - member_name = "disks" # map to each.value.subresource_name if there are multiple services. - private_ip_address = ip_configuration.value.private_ip_address + name = each.value.private_dns_zone_group_name + private_dns_zone_ids = each.value.private_dns_zone_resource_ids } -} + } } # 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 } - - name = each.value.name != null ? each.value.name : "pep-${var.name}" - location = each.value.location != null ? each.value.location : var.location - 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 - tags = each.value.tags + for_each = { for k, v in var.private_endpoints : k => v if !var.private_endpoints_manage_dns_zone_group } - private_service_connection { - name = each.value.private_service_connection_name != null ? each.value.private_service_connection_name : "pse-${var.name}" - private_connection_resource_id = var.disk_access_id - is_manual_connection = false - subresource_names = ["disks"] # map to each.value.subresource_name if there are multiple services. - } + location = each.value.location != null ? each.value.location : var.location + 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 + tags = each.value.tags - dynamic "ip_configuration" { - for_each = each.value.ip_configurations + 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 = 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 - content { - name = ip_configuration.value.name - subresource_name = "disks" # map to each.value.subresource_name if there are multiple services. - member_name = "disks" # map to each.value.subresource_name if there are multiple services. - private_ip_address = ip_configuration.value.private_ip_address - } + content { + name = ip_configuration.value.name + private_ip_address = ip_configuration.value.private_ip_address + 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. } + } - lifecycle { - ignore_changes = [private_dns_zone_group] - } + lifecycle { + ignore_changes = [private_dns_zone_group] + } } resource "azurerm_private_endpoint_application_security_group_association" "this" { -for_each = local.private_endpoint_application_security_group_associations -private_endpoint_id = azurerm_private_endpoint.this_managed_dns_zone_groups[each.value.pe_key].id -application_security_group_id = each.value.asg_resource_id + for_each = local.private_endpoint_application_security_group_associations + + application_security_group_id = each.value.asg_resource_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 d90dd47..7316a37 100644 --- a/main.tf +++ b/main.tf @@ -10,8 +10,9 @@ resource "azurerm_management_lock" "this" { resource "azurerm_role_assignment" "this" { for_each = var.role_assignments + principal_id = each.value.principal_id - scope = azurerm_managed_disk.this.id + 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 diff --git a/outputs.tf b/outputs.tf index 9d0558d..27e77cd 100644 --- a/outputs.tf +++ b/outputs.tf @@ -3,17 +3,12 @@ output "location" { value = var.location } -output "resource_group_name" { - description = "The name of the Resource Group." - value = var.resource_group_name -} - # 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" { -value = var.private_endpoints_manage_dns_zone_group ? azurerm_private_endpoint.this_managed_dns_zone_groups : azurerm_private_endpoint.this_unmanaged_dns_zone_groups -description = <. -If it is set to false, then no telemetry will be collected. -DESCRIPTION -} - -variable "location" { - type = string - nullable = false - description = "Azure region where the resource should be deployed." -} - -variable "lock" { - type = object({ - kind = string - name = optional(string, null) - }) - default = null - description = < Note: only set `skip_service_principal_aad_check` to true if you are assigning a role to a service principal. -DESCRIPTION - nullable = false -} - - -# tflint-ignore: terraform_unused_declarations -variable "tags" { - type = map(string) - default = null - description = "(Optional) Tags of the resource." -} - - -variable "create_option" { - type = string - description = "(Required) The method to use when creating the managed disk. Changing this forces a new resource to be created. Possible values include: * `Import`" - nullable = false - validation { - condition = contains(["Attach", "Copy", "CopyStart", "Empty", "FromImage", "Import", "ImportSecure", "Restore", "Upload", "UploadPreparedSecure"], var.create_option) - error_message = "The create option must be one of: 'Attach', 'Copy', CopyStart', 'Empty', 'FromImage', 'Import', 'ImportSecure', 'Restore', 'Upload', 'UploadPreparedSecure'." - } -} - -variable "storage_account_type" { - type = string - 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`." - nullable = false - validation { - condition = can(regex("^(Standard_LRS|StandardSSD_ZRS|Premium_LRS|PremiumV2_LRS|Premium_ZRS|StandardSSD_LRS|UltraSSD_LRS)$", var.storage_account_type)) - error_message = "The storage account type must be one of: 'Standard_LRS', 'StandardSSD_ZRS', 'Premium_LRS', 'PremiumV2_LRS', 'Premium_ZRS', 'StandardSSD_LRS', 'UltraSSD_LRS'." - } -} - variable "disk_access_id" { type = string default = null @@ -278,6 +158,16 @@ variable "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." } +variable "enable_telemetry" { + type = bool + default = true + description = <. +If it is set to false, then no telemetry will be collected. +DESCRIPTION +} + variable "encryption_settings" { type = object({ enabled = optional(bool) @@ -324,6 +214,25 @@ variable "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." } +variable "lock" { + type = object({ + kind = string + name = optional(string, null) + }) + default = null + description = < Note: only set `skip_service_principal_aad_check` to true if you are assigning a role to a service principal. +DESCRIPTION + nullable = false +} + variable "secure_vm_disk_encryption_set_id" { type = string default = null @@ -402,6 +394,13 @@ variable "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." } +# tflint-ignore: terraform_unused_declarations +variable "tags" { + type = map(string) + default = null + description = "(Optional) Tags of the resource." +} + variable "tier" { type = string default = null From 07f64f6b7bb9c1684b7e59343b7d6e344b9e854b Mon Sep 17 00:00:00 2001 From: terrymandin Date: Mon, 6 May 2024 15:01:32 -0600 Subject: [PATCH 11/13] Set required version of TF to 1.7 --- examples/default/terraform.tf | 2 +- terraform.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/default/terraform.tf b/examples/default/terraform.tf index 0a62505..8dc4e9e 100644 --- a/examples/default/terraform.tf +++ b/examples/default/terraform.tf @@ -1,5 +1,5 @@ terraform { - required_version = "~> 1.6" + required_version = "~> 1.7" required_providers { azurerm = { source = "hashicorp/azurerm" diff --git a/terraform.tf b/terraform.tf index b784adb..6dfc875 100644 --- a/terraform.tf +++ b/terraform.tf @@ -1,5 +1,5 @@ terraform { - required_version = "~> 1.5" + required_version = "~> 1.7" required_providers { # TODO: Ensure all required providers are listed here and the version property includes a constraint on the maximum major version. azurerm = { From be1bf370a5959a927b59f5a2b426d9f06d9e2c20 Mon Sep 17 00:00:00 2001 From: terrymandin Date: Tue, 7 May 2024 11:04:43 -0600 Subject: [PATCH 12/13] avmfix, pre-commit --- README.md | 361 +++++++++++++++--- examples/default/README.md | 81 ++-- examples/diagnostic-settings/README.md | 91 +++-- examples/diagnostic-settings/main.tf | 12 +- examples/diagnostic-settings/outputs.tf | 10 +- examples/diagnostic-settings/variables.tf | 2 +- .../{README copy.md => README.md} | 86 +++-- examples/encrypted-disk/dependencies.tf | 21 +- examples/encrypted-disk/main.tf | 8 +- examples/encrypted-disk/outputs.tf | 10 +- examples/encrypted-disk/variables.tf | 2 +- examples/private-endpoint/README.md | 120 ++++-- examples/private-endpoint/main.tf | 28 +- examples/private-endpoint/outputs.tf | 10 +- examples/private-endpoint/variables.tf | 2 +- 15 files changed, 571 insertions(+), 273 deletions(-) rename examples/encrypted-disk/{README copy.md => README.md} (65%) 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/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/diagnostic-settings/README.md b/examples/diagnostic-settings/README.md index 1abcc3c..44a3922 100644 --- a/examples/diagnostic-settings/README.md +++ b/examples/diagnostic-settings/README.md @@ -1,33 +1,13 @@ # Default example -This deploys the module in its simplest form. +This deploys the module with diagnostic settings enabled. ```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" { source = "Azure/regions/azurerm" - version = "~> 0.3" + version = ">= 0.3.0" } # This allows us to randomize the region for the resource group. @@ -35,33 +15,47 @@ resource "random_integer" "region_index" { max = length(module.regions.regions) - 1 min = 0 } -## End of section to provide a random Azure region for the resource group # This ensures we have unique CAF compliant names for our resources. module "naming" { source = "Azure/naming/azurerm" - version = "~> 0.3" + 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 -# 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 + diagnostic_settings = { + to_la = { + name = "to-la" + workspace_resource_id = azurerm_log_analytics_workspace.this.id + } + } } ``` @@ -70,7 +64,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) @@ -88,6 +82,7 @@ The following providers are used by this module: 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) @@ -103,7 +98,7 @@ 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 . +For more information see https://aka.ms/avm/telemetryinfo. If it is set to false, then no telemetry will be collected. Type: `bool` @@ -112,29 +107,41 @@ 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 -Version: ~> 0.3 +Version: 0.3.0 ### [regions](#module\_regions) Source: Azure/regions/azurerm -Version: ~> 0.3 - -### [test](#module\_test) - -Source: ../../ - -Version: +Version: >= 0.3.0 ## Data Collection diff --git a/examples/diagnostic-settings/main.tf b/examples/diagnostic-settings/main.tf index 1212c9b..6a23e78 100644 --- a/examples/diagnostic-settings/main.tf +++ b/examples/diagnostic-settings/main.tf @@ -20,14 +20,14 @@ 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 + 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 + tags = local.tags } # This is the module call @@ -39,11 +39,11 @@ module "disk" { 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" + enable_telemetry = var.enable_telemetry # see variables.tf + create_option = "Empty" storage_account_type = "PremiumV2_LRS" - disk_size_gb = 1024 - tags = local.tags + disk_size_gb = 1024 + tags = local.tags diagnostic_settings = { to_la = { name = "to-la" diff --git a/examples/diagnostic-settings/outputs.tf b/examples/diagnostic-settings/outputs.tf index dd78112..d204d79 100644 --- a/examples/diagnostic-settings/outputs.tf +++ b/examples/diagnostic-settings/outputs.tf @@ -3,12 +3,12 @@ output "location" { 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 } - -output "resource" { - description = "This is the full output for the resource." - value = module.disk.resource -} \ No newline at end of file diff --git a/examples/diagnostic-settings/variables.tf b/examples/diagnostic-settings/variables.tf index 4e20ee8..1318944 100644 --- a/examples/diagnostic-settings/variables.tf +++ b/examples/diagnostic-settings/variables.tf @@ -6,4 +6,4 @@ 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. DESCRIPTION -} \ No newline at end of file +} diff --git a/examples/encrypted-disk/README copy.md b/examples/encrypted-disk/README.md similarity index 65% rename from examples/encrypted-disk/README copy.md rename to examples/encrypted-disk/README.md index 1abcc3c..fa1fff7 100644 --- a/examples/encrypted-disk/README copy.md +++ b/examples/encrypted-disk/README.md @@ -1,33 +1,13 @@ # Default example -This deploys the module in its simplest form. +This example deploys an encrypted disk. ```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" { source = "Azure/regions/azurerm" - version = "~> 0.3" + version = ">= 0.3.0" } # This allows us to randomize the region for the resource group. @@ -35,12 +15,11 @@ resource "random_integer" "region_index" { max = length(module.regions.regions) - 1 min = 0 } -## End of section to provide a random Azure region for the resource group # This ensures we have unique CAF compliant names for our resources. module "naming" { source = "Azure/naming/azurerm" - version = "~> 0.3" + version = "0.3.0" } # This is required for resource modules @@ -50,18 +29,19 @@ resource "azurerm_resource_group" "this" { } # 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 + disk_encryption_set_id = azurerm_disk_encryption_set.this.id } ``` @@ -70,7 +50,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) @@ -88,8 +68,12 @@ The following providers are used by this module: 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 @@ -103,7 +87,7 @@ 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 . +For more information see https://aka.ms/avm/telemetryinfo. If it is set to false, then no telemetry will be collected. Type: `bool` @@ -112,29 +96,47 @@ 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: + +### [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 +Version: 0.3.0 ### [regions](#module\_regions) Source: Azure/regions/azurerm -Version: ~> 0.3 - -### [test](#module\_test) - -Source: ../../ - -Version: +Version: >= 0.3.0 ## Data Collection diff --git a/examples/encrypted-disk/dependencies.tf b/examples/encrypted-disk/dependencies.tf index f1f7f2e..1f238d8 100644 --- a/examples/encrypted-disk/dependencies.tf +++ b/examples/encrypted-disk/dependencies.tf @@ -1,8 +1,8 @@ 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 + 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 + tags = local.tags } data "azurerm_client_config" "current" {} @@ -11,7 +11,7 @@ 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 + tags = local.tags } module "key_vault" { @@ -22,7 +22,7 @@ module "key_vault" { resource_group_name = azurerm_resource_group.this.name location = azurerm_resource_group.this.location enabled_for_deployment = true - tags = local.tags + tags = local.tags network_acls = { default_action = "Allow" @@ -32,11 +32,11 @@ module "key_vault" { // 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" + 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" + role_definition_id_or_name = "Key Vault Crypto Service Encryption User" principal_id = azurerm_user_assigned_identity.this.principal_id } } @@ -55,7 +55,7 @@ module "key_vault" { key_vault_id = module.key_vault.resource.id name = "cmkfordisk" key_size = 2048 - tags = local.tags + tags = local.tags } } @@ -65,13 +65,14 @@ module "key_vault" { } 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" + type = "UserAssigned" identity_ids = [azurerm_user_assigned_identity.this.id] } - key_vault_key_id = module.key_vault.resource_keys["cmkfordisk"].id - tags = local.tags } diff --git a/examples/encrypted-disk/main.tf b/examples/encrypted-disk/main.tf index ebffb30..05b09f0 100644 --- a/examples/encrypted-disk/main.tf +++ b/examples/encrypted-disk/main.tf @@ -31,9 +31,9 @@ module "disk" { 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 + 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 index dd78112..d204d79 100644 --- a/examples/encrypted-disk/outputs.tf +++ b/examples/encrypted-disk/outputs.tf @@ -3,12 +3,12 @@ output "location" { 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 } - -output "resource" { - description = "This is the full output for the resource." - value = module.disk.resource -} \ No newline at end of file diff --git a/examples/encrypted-disk/variables.tf b/examples/encrypted-disk/variables.tf index 4e20ee8..1318944 100644 --- a/examples/encrypted-disk/variables.tf +++ b/examples/encrypted-disk/variables.tf @@ -6,4 +6,4 @@ 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. DESCRIPTION -} \ No newline at end of file +} diff --git a/examples/private-endpoint/README.md b/examples/private-endpoint/README.md index 1abcc3c..06406cf 100644 --- a/examples/private-endpoint/README.md +++ b/examples/private-endpoint/README.md @@ -1,33 +1,13 @@ # Default example -This deploys the module in its simplest form. +This deploys a disk with a private endpoint. ```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" { source = "Azure/regions/azurerm" - version = "~> 0.3" + version = ">= 0.3.0" } # This allows us to randomize the region for the resource group. @@ -35,33 +15,73 @@ resource "random_integer" "region_index" { max = length(module.regions.regions) - 1 min = 0 } -## End of section to provide a random Azure region for the resource group # This ensures we have unique CAF compliant names for our resources. module "naming" { source = "Azure/naming/azurerm" - version = "~> 0.3" + 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 -# 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 + 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 + } + } } ``` @@ -70,7 +90,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) @@ -88,7 +108,11 @@ The following providers are used by this module: 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) @@ -103,7 +127,7 @@ 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 . +For more information see https://aka.ms/avm/telemetryinfo. If it is set to false, then no telemetry will be collected. Type: `bool` @@ -112,29 +136,41 @@ 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 -Version: ~> 0.3 +Version: 0.3.0 ### [regions](#module\_regions) Source: Azure/regions/azurerm -Version: ~> 0.3 - -### [test](#module\_test) - -Source: ../../ - -Version: +Version: >= 0.3.0 ## Data Collection diff --git a/examples/private-endpoint/main.tf b/examples/private-endpoint/main.tf index bb6d872..de646b2 100644 --- a/examples/private-endpoint/main.tf +++ b/examples/private-endpoint/main.tf @@ -20,7 +20,7 @@ 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 + tags = local.tags } # A vnet is required for the private endpoint. @@ -29,7 +29,7 @@ resource "azurerm_virtual_network" "this" { location = azurerm_resource_group.this.location name = module.naming.virtual_network.name_unique resource_group_name = azurerm_resource_group.this.name - tags = local.tags + tags = local.tags } resource "azurerm_subnet" "this" { @@ -42,14 +42,14 @@ resource "azurerm_subnet" "this" { resource "azurerm_private_dns_zone" "this" { name = "privatelink.blob.core.windows.net" resource_group_name = azurerm_resource_group.this.name - tags = local.tags + 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 + 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 + tags = local.tags } # This is the module call @@ -61,19 +61,19 @@ module "disk" { 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 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 + 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 ] + 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 + subnet_resource_id = azurerm_subnet.this.id } } } diff --git a/examples/private-endpoint/outputs.tf b/examples/private-endpoint/outputs.tf index dd78112..d204d79 100644 --- a/examples/private-endpoint/outputs.tf +++ b/examples/private-endpoint/outputs.tf @@ -3,12 +3,12 @@ output "location" { 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 } - -output "resource" { - description = "This is the full output for the resource." - value = module.disk.resource -} \ No newline at end of file diff --git a/examples/private-endpoint/variables.tf b/examples/private-endpoint/variables.tf index 4e20ee8..1318944 100644 --- a/examples/private-endpoint/variables.tf +++ b/examples/private-endpoint/variables.tf @@ -6,4 +6,4 @@ 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. DESCRIPTION -} \ No newline at end of file +} From d3b26d9f2e59b856eea04c2ee204bcdec479f8e9 Mon Sep 17 00:00:00 2001 From: terrymandin Date: Tue, 7 May 2024 11:40:51 -0600 Subject: [PATCH 13/13] Updated Private Endpoint interface --- README.md | 34 +++++++++++++++++----------------- variables.tf | 36 ++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 4e5e10e..ab652bd 100644 --- a/README.md +++ b/README.md @@ -342,23 +342,23 @@ Default: `null` ### [private\_endpoints](#input\_private\_endpoints) -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. +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: diff --git a/variables.tf b/variables.tf index d22c795..63d6592 100644 --- a/variables.tf +++ b/variables.tf @@ -300,24 +300,24 @@ variable "private_endpoints" { })) default = {} description = <