From 39b5cabda80598aa8930e4b87ae26f306c25ac1f Mon Sep 17 00:00:00 2001 From: Viktor Ribchev Date: Mon, 27 Nov 2023 15:23:54 +0200 Subject: [PATCH] Updated the DNS module not to use data sources Added additional variables Added script, which creates DNS records based on the attached disk Changed disk naming to "Disk-$${RESOURCE_GROUP}-$${ZONE_ID}-$${DISK_ORDER}" Fixed an issue where the attach disk script was failing --- main.tf | 24 +++-------- modules/dns/main.tf | 29 ++++--------- modules/dns/variables.tf | 29 ++++++------- modules/vm/templates/entrypoint.sh.tpl | 57 +++++++++++++++++++------- variables.tf | 7 ---- 5 files changed, 71 insertions(+), 75 deletions(-) diff --git a/main.tf b/main.tf index 35b3f57..5d15b48 100644 --- a/main.tf +++ b/main.tf @@ -307,28 +307,16 @@ module "backup" { tags = local.tags } - module "dns" { source = "./modules/dns" - resource_name_prefix = var.resource_name_prefix - identity_name = module.identity.identity_name - - depends_on = [ - azurerm_resource_group.graphdb, - azurerm_virtual_network.graphdb, - azurerm_subnet.graphdb-vmss, - module.configuration, - module.identity - ] -} - - -module "dns" { - source = "./modules/dns" + resource_name_prefix = var.resource_name_prefix + resource_group_name = azurerm_resource_group.graphdb.name + identity_name = module.identity.identity_name + identity_principal_id = module.identity.identity_principal_id + virtual_network_id = azurerm_virtual_network.graphdb.id - resource_name_prefix = var.resource_name_prefix - identity_name = module.identity.identity_name + tags = local.tags depends_on = [ azurerm_resource_group.graphdb, diff --git a/modules/dns/main.tf b/modules/dns/main.tf index 56ff0b5..0c26877 100644 --- a/modules/dns/main.tf +++ b/modules/dns/main.tf @@ -1,32 +1,19 @@ -data "azurerm_resource_group" "graphdb" { - name = var.resource_name_prefix -} - -data "azurerm_user_assigned_identity" "graphdb-instances" { - name = var.identity_name - resource_group_name = var.resource_name_prefix -} - -data "azurerm_virtual_network" "graphdb" { - name = var.resource_name_prefix - resource_group_name = data.azurerm_resource_group.graphdb.name -} - resource "azurerm_private_dns_zone" "zone" { name = "${var.resource_name_prefix}.dns.zone" - resource_group_name = data.azurerm_resource_group.graphdb.name + resource_group_name = var.resource_group_name + tags = var.tags } resource "azurerm_private_dns_zone_virtual_network_link" "zone_link" { name = "${var.resource_name_prefix}-dns-link" - resource_group_name = data.azurerm_resource_group.graphdb.name + resource_group_name = var.resource_group_name private_dns_zone_name = azurerm_private_dns_zone.zone.name - virtual_network_id = data.azurerm_virtual_network.graphdb.id - registration_enabled = true + virtual_network_id = var.virtual_network_id + tags = var.tags } resource "azurerm_role_assignment" "dns_zone_role_assignment" { - principal_id = data.azurerm_user_assigned_identity.graphdb-instances.principal_id - role_definition_name = "DNS Zone Contributor" - scope = azurerm_private_dns_zone_virtual_network_link.zone_link.id + principal_id = var.identity_principal_id + role_definition_name = "Private DNS Zone Contributor" + scope = azurerm_private_dns_zone.zone.id } diff --git a/modules/dns/variables.tf b/modules/dns/variables.tf index b284e63..f2af821 100644 --- a/modules/dns/variables.tf +++ b/modules/dns/variables.tf @@ -1,3 +1,8 @@ +variable "resource_group_name" { + description = "Resource group name where the DNS zone will be created" + type = string +} + variable "resource_name_prefix" { description = "Resource name prefix used for tagging and naming Azure resources" type = string @@ -8,27 +13,23 @@ variable "resource_name_prefix" { } } -variable "zone_dns_name" { - description = "DNS name for the private DNS zone in Azure" - type = string -} - -variable "resource_group_name" { - description = "Resource group name where the DNS zone will be created" - type = string -} - variable "identity_name" { description = "Name of a user assigned identity with permissions" type = string } -variable "zone_dns_name" { - description = "DNS name for the private DNS zone in Azure" +variable "virtual_network_id" { + description = "Virtual network the DNS will be linked to" type = string } -variable "resource_group_name" { - description = "Resource group name where the DNS zone will be created" +variable "tags" { + description = "Common resource tags." + type = map(string) + default = {} +} + +variable "identity_principal_id" { + description = "Principal identifier of a user assigned identity with permissions" type = string } diff --git a/modules/vm/templates/entrypoint.sh.tpl b/modules/vm/templates/entrypoint.sh.tpl index fec1cba..6c8cd96 100644 --- a/modules/vm/templates/entrypoint.sh.tpl +++ b/modules/vm/templates/entrypoint.sh.tpl @@ -13,11 +13,11 @@ az login --identity # Find/create/attach volumes INSTANCE_HOSTNAME=\'$(hostname)\' SUBSCRIPTION_ID=$(az account show --query "id" --output tsv) -RESOURSE_GROUP=$(az vmss list --query "[0].resourceGroup" --output tsv) +RESOURCE_GROUP=$(az vmss list --query "[0].resourceGroup" --output tsv) VMSS_NAME=$(az vmss list --query "[0].name" --output tsv) -INSTANCE_ID=$(az vmss list-instances --resource-group $RESOURSE_GROUP --name $VMSS_NAME --query "[?contains(osProfile.computerName, $${INSTANCE_HOSTNAME})].instanceId" --output tsv) -ZONE_ID=$(az vmss list-instances --resource-group $RESOURSE_GROUP --name $VMSS_NAME --query "[?contains(osProfile.computerName, $${INSTANCE_HOSTNAME})].zones" --output tsv) -REGION_ID=$(az vmss list-instances --resource-group $RESOURSE_GROUP --name $VMSS_NAME --query "[?contains(osProfile.computerName, $${INSTANCE_HOSTNAME})].location" --output tsv) +INSTANCE_ID=$(az vmss list-instances --resource-group $RESOURCE_GROUP --name $VMSS_NAME --query "[?contains(osProfile.computerName, $${INSTANCE_HOSTNAME})].instanceId" --output tsv) +ZONE_ID=$(az vmss list-instances --resource-group $RESOURCE_GROUP --name $VMSS_NAME --query "[?contains(osProfile.computerName, $${INSTANCE_HOSTNAME})].zones" --output tsv) +REGION_ID=$(az vmss list-instances --resource-group $RESOURCE_GROUP --name $VMSS_NAME --query "[?contains(osProfile.computerName, $${INSTANCE_HOSTNAME})].location" --output tsv) # Do NOT change the LUN. Based on this we find and mount the disk in the VM LUN=2 @@ -25,14 +25,11 @@ DISK_IOPS=${disk_iops_read_write} DISK_THROUGHPUT=${disk_mbps_read_write} DISK_SIZE_GB=${disk_size_gb} -# TODO Define the disk name based on the hostname ?? -diskName="Disk_$${VMSS_NAME}_$${INSTANCE_ID}" - for i in $(seq 1 6); do # Wait for existing disks in the VMSS which are unattached existingUnattachedDisk=$( - az disk list --resource-group $RESOURSE_GROUP \ - --query "[?diskState=='Unattached' && starts_with(name, 'Disk_$${VMSS_NAME}')].{Name:name}" \ + az disk list --resource-group $RESOURCE_GROUP \ + --query "[?diskState=='Unattached' && starts_with(name, 'Disk-$${RESOURCE_GROUP}') && zones[0]=='$${ZONE_ID}'].{Name:name}" \ --output tsv ) @@ -46,7 +43,16 @@ done if [ -z "$existingUnattachedDisk" ]; then echo "Creating a new managed disk" - az disk create --resource-group $RESOURSE_GROUP \ + # Fetch the number of elements + numElements=$(az disk list --query "length([?zones[0]=='$${ZONE_ID}'])" --output tsv) + + # Increment the number for the new name + DISK_ORDER=$((numElements + 1)) + + # TODO Define the disk name based on the hostname ?? + diskName="Disk-$${RESOURCE_GROUP}-$${ZONE_ID}-$${DISK_ORDER}" + + az disk create --resource-group $RESOURCE_GROUP \ --name $diskName \ --size-gb $DISK_SIZE_GB \ --location $REGION_ID \ @@ -55,23 +61,24 @@ if [ -z "$existingUnattachedDisk" ]; then --os-type Linux \ --disk-iops-read-write $DISK_IOPS \ --disk-mbps-read-write $DISK_THROUGHPUT \ + --tags createdBy=$INSTANCE_HOSTNAME \ --public-network-access Disabled \ --network-access-policy DenyAll fi # Checks if a managed disk is attached to the instance -attachedDisk=$(az vmss list-instances --resource-group "$RESOURSE_GROUP" --name "$VMSS_NAME" --query "[?instanceId==\"$INSTANCE_ID\"].storageProfile.dataDisks[].name" --output tsv) +attachedDisk=$(az vmss list-instances --resource-group "$RESOURCE_GROUP" --name "$VMSS_NAME" --query "[?instanceId==\"$INSTANCE_ID\"].storageProfile.dataDisks[].name" --output tsv) if [ -z "$attachedDisk" ]; then echo "No data disks attached for instance ID $INSTANCE_ID in VMSS $VMSS_NAME." # Try to attach an existing managed disk - availableDisks=$(az disk list --resource-group $RESOURSE_GROUP --query "[?diskState=='Unattached' && starts_with(name, 'Disk_$${VMSS_NAME}') && zones[0]=='$${ZONE_ID}'].{Name:name}" --output tsv) + availableDisks=$(az disk list --resource-group $RESOURCE_GROUP --query "[?diskState=='Unattached' && starts_with(name, 'Disk-$${RESOURCE_GROUP}') && zones[0]=='$${ZONE_ID}'].{Name:name}" --output tsv) echo "Attaching available disk $availableDisks." # Set Internal Field Separator to newline to handle spaces in names IFS=$'\n' # Would iterate through all available disks and attempt to attach them for availableDisk in $availableDisks; do - az vmss disk attach --vmss-name $VMSS_NAME --resource-group $RESOURSE_GROUP --instance-id $INSTANCE_ID --lun $LUN --disk "$availableDisk" || true + az vmss disk attach --vmss-name $VMSS_NAME --resource-group $RESOURCE_GROUP --instance-id $INSTANCE_ID --lun $LUN --disk "$availableDisk" || true done fi @@ -120,8 +127,28 @@ chown -R graphdb:graphdb /var/opt/graphdb # DNS hack # -# TODO: Should be based on something stable, e.g. volume id -node_dns=$(hostname) +# TODO This won't handle cases where we have 2 VMs in 1 AZ. Since we cannot change the computerName when in VMSS our hands are tied + +ZONE_NAME=$(az network private-dns zone list --query "[].name" --output tsv) +IP_ADDRESS=$(hostname -I | xargs) +VMSS_INSTANCE_NAME=$(curl -H Metadata:true "http://169.254.169.254/metadata/instance/compute/name?api-version=2021-01-01&format=text") +ATTACHED_DISK_NAME=$(az disk list --query "[?diskState == 'Attached' && contains(managedBy, '$${VMSS_INSTANCE_NAME}')].name" --output tsv) +RECORD_NAME="$( echo -n "$ATTACHED_DISK_NAME" | sed 's/^Disk/Node/' )" + +EXISTING_DNS_RECORD=$(az network private-dns record-set a show --resource-group $RESOURCE_GROUP --zone-name $ZONE_NAME --name $RECORD_NAME --output json) || EXISTING_DNS_RECORD="" + + if [ -z "$EXISTING_DNS_RECORD" ]; then + echo "Creating a new DNS record..." + az network private-dns record-set a add-record --resource-group $RESOURCE_GROUP --zone-name $ZONE_NAME --record-set-name $RECORD_NAME --ipv4-address "$IP_ADDRESS" + echo "DNS record created successfully." + else + echo "Updating existing DNS record..." + az network private-dns record-set a update --resource-group $RESOURCE_GROUP --zone-name $ZONE_NAME --name $RECORD_NAME --set ARecords[0].ipv4Address="$IP_ADDRESS" + echo "DNS record updated successfully." + fi + +# Gets the full DNS record for the current instance +node_dns=$(az network private-dns record-set a show --resource-group $RESOURCE_GROUP --zone-name $ZONE_NAME --name $RECORD_NAME --output tsv --query "fqdn" | rev | cut -c 2- | rev) # # GraphDB configuration overrides diff --git a/variables.tf b/variables.tf index 5eb8c37..7e83cb9 100644 --- a/variables.tf +++ b/variables.tf @@ -206,10 +206,3 @@ variable "bastion_subnet_address_prefix" { type = list(string) default = ["10.0.3.0/27"] } - -# DNS - -variable "zone_dns_name" { - description = "Zone DNS Name" - type = string -}