Home NewsX Transition from VNET integration to public access or Private Link using the Azure CLI

Transition from VNET integration to public access or Private Link using the Azure CLI

by info.odysseyx@gmail.com
0 comment 5 views


You can switch. Azure Database for MySQL Flexible Server From using VNET integration (private access) to seamlessly using public access or private links without having to change server names or migrate data, we simplify the process for our customers. However, once you make the switch there is no going back. The switchover requires approximately 5 to 10 minutes of downtime for non-HA servers and approximately 20 minutes of downtime for HA-capable servers.

memo: Step-by-step instructions for transitioning your Azure Database for MySQL Flexible Server from using an integrated VNET to using public access or private link through the Azure portal can be found in the article. Move from private access to public access or private link using the Azure portal.

This post provides two bash scripts to switch an Azure Database for MySQL flexible server from VNET integration to public access or private link using the Azure CLI. These bash scripts can be run locally or using: Azure cloud shell.

MysqlVnetToPublic.sh

This script allows you to switch from using an integrated VNET to using public access using firewall rules. The default VNET and subnet of the flexible server do not change. The script accepts one firewall rule as input, but you can modify it to add multiple firewall rules if necessary. The script isolates the VNET from the flexible server, enables public access, and then creates firewall rules.

#!/bin/bash
#
# PURPOSE
# Migrate Azure Database for MySQL Flexible Server from VNET Integrated to Public Access
# 
# DESCRIPTION
# Move from private access (virtual network integrated) to public access
# https://learn.microsoft.com/en-us/azure/mysql/flexible-server/how-to-network-from-private-to-public
#
# PREREQUISITES
# Azure CLI (https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)
# 
# ARGUMENTS
# --subscription-id -s     [Required] : Subscription ID.
# --resource-group-name -g [Required] : Name of resource group.
# --server-name -n         [Required] : Name of the server.
# --rule-name -r           [Required] : The name of the firewall rule. The firewall rule name can
#                                       only contain 0-9, a-z, A-Z, '-' and '_'. Additionally, the name
#                                       of the firewall rule must be at least 1 character and no more
#                                       than 80 characters in length.
# --start-ip-address -a    [Required] : The start IP address of the firewall rule. Must be IPv4 format.
#                                       Use value '0.0.0.0' to represent all Azure-internal IP addresses.
# --end-ip-address -b      [Required] : The end IP address of the firewall rule. Must be IPv4 format.
#                                       Use value '0.0.0.0' to represent all Azure-internal IP addresses.
#
# USAGE
# bash mysqlVnetToPublic.sh
#         --subscription-id 'ffffffff-ffff-ffff-ffff-ffffffffffff'
#         --resource-group-name 'mysqlRG'
#         --server-name 'mysqlflex'
#         --firewall-rule-name 'allowiprange'
#         --start-ip-address 107.46.14.0
#         --end-ip-address 107.46.14.221
#

function usage()
{
    echo ""
    echo "PURPOSE"
    echo "Migrate Azure Database for MySQL Flexible Server from VNET Integrated to Public Access"
    echo ""
    echo "DESCRIPTION"
    echo "Move from private access (virtual network integrated) to public access"
    echo "https://learn.microsoft.com/en-us/azure/mysql/flexible-server/how-to-network-from-private-to-public"
    echo ""
    echo "PREREQUISITES"
    echo "Azure CLI (https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)"
    echo ""
    echo "ARGUMENTS"
    echo " --subscription-id -s     [Required] : Subscription ID."
    echo " --resource-group-name -g [Required] : Name of resource group."
    echo " --server-name -n         [Required] : Name of the server."
    echo " --rule-name -r           [Required] : The name of the firewall rule. The firewall rule name can"
    echo "                                       only contain 0-9, a-z, A-Z, '-' and '_'. Additionally, the name"
    echo "                                       of the firewall rule must be at least 1 character and no more"
    echo "                                       than 80 characters in length."
    echo " --start-ip-address -a    [Required] : The start IP address of the firewall rule. Must be IPv4 format."
    echo "                                       Use value '0.0.0.0' to represent all Azure-internal IP addresses."
    echo " --end-ip-address -b      [Required] : The end IP address of the firewall rule. Must be IPv4 format."
    echo "                                       Use value '0.0.0.0' to represent all Azure-internal IP addresses."
    echo ""
    echo "USAGE"
    echo "bash mysqlVnetToPublic.sh"
    echo -e "\t--subscription-id 'ffffffff-ffff-ffff-ffff-ffffffffffff'"
    echo -e "\t--resource-group-name 'mysqlRG'"
    echo -e "\t--server-name 'mysqlflex'"
    echo -e "\t--firewall-rule-name 'allowiprange'"
    echo -e "\t--start-ip-address 107.46.14.0"
    echo -e "\t--end-ip-address 107.46.14.221"
    echo ""
    exit 1
}

PARAMS=""
while (( "$#" )); do
  case "$1" in
    -h | --help)
      usage
      exit
      ;;
    -s|--subscription-id)
      SUBSCRIPTION_ID=$2
      shift 2
      ;;
    -g|--resource-group-name)
      RESOURCE_GROUP_NAME=$2
      shift 2
      ;;
    -n|--server-name)
      SERVER_NAME=$2
      shift 2
      ;;
    -r|--firewall-rule-name)
      FIREWALL_RULE_NAME=$2
      shift 2
      ;;
    -a|--start-ip-address)
      START_IP_ADDRESS=$2
      shift 2
      ;;
    -b|--end-ip-address)
      END_IP_ADDRESS=$2
      shift 2
      ;;
    --) # end argument parsing
      shift
      break
      ;;
    -*|--*=) # unsupported flags
      echo "Error: Unsupported flag $1" >&2
      exit 1
      ;;
    *) # preserve positional arguments
      PARAMS="$PARAMS $1"
      shift
      ;;
  esac
done
# set positional arguments in their proper place
eval set -- "$PARAMS"

# Ensure required parameters are provided
if [ -z "$SUBSCRIPTION_ID" ]; then
    echo "Error: Subscription ID is required"
    usage
fi

if [ -z "$RESOURCE_GROUP_NAME" ]; then
    echo "Error: Resource Group Name is required"
    usage
fi

if [ -z "$SERVER_NAME" ]; then
    echo "Error: Server Name is required"
    usage
fi

if [ -z "$FIREWALL_RULE_NAME" ]; then
    echo "Error: Firewall Rule Name is required"
    usage
fi

if [ -z "$START_IP_ADDRESS" ]; then
    echo "Error: Start IP Address is required"
    usage
fi

if [ -z "$END_IP_ADDRESS" ]; then
    echo "Error: End IP Address is required"
    usage
fi

# Prerequisites - Install Azure CLI package
if ! [ -x "$(command -v az)" ]; then
  echo 'Error: azure cli is not installed. Please install from https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest' >&2
  exit 1
fi

# Check if the subscription exists
if ! az account list --query "[?id=='$SUBSCRIPTION_ID' || name=='$SUBSCRIPTION_ID'].id" -o tsv | grep -q .; then
    echo "Subscription '$SUBSCRIPTION_ID' does not exist."
    exit 1
fi

# Set subscription
az account set --subscription "$SUBSCRIPTION_ID"

# Check if the resource group exists
if ! az group show --name "$RESOURCE_GROUP_NAME" > /dev/null 2>&1; then
    echo "Resource group '$RESOURCE_GROUP_NAME' does not exist."
    exit 1 
fi

# Check if the MySQL Flexible server exists
if ! az mysql flexible-server show --resource-group "$RESOURCE_GROUP_NAME" --name "$SERVER_NAME" > /dev/null 2>&1; then
    echo "MySQL Flexible Server '$SERVER_NAME' does not exist in resource group '$RESOURCE_GROUP_NAME'."
    exit 1
fi

# Ensure server is VNET Integrated
DELEGATED_SUBNET_RESOURCE_ID=$(az mysql flexible-server show --resource-group "$RESOURCE_GROUP_NAME" --name "$SERVER_NAME" --query "network.delegatedSubnetResourceId" --output tsv)
if [ -z "$DELEGATED_SUBNET_RESOURCE_ID" ]; then
    echo "Error: MySQL Flexible Server is not VNET Integrated"
    exit 1
fi

echo "Detaching VNET from server $SERVER_NAME"
az mysql flexible-server detach-vnet --resource-group "$RESOURCE_GROUP_NAME"  --name "$SERVER_NAME" --public-network-access Enabled --yes

echo "Creating Firewall Rule on server $SERVER_NAME"
az mysql flexible-server firewall-rule create \
  --resource-group "$RESOURCE_GROUP_NAME"  \
  --name "$SERVER_NAME" \
  --rule-name "$FIREWALL_RULE_NAME" \
  --start-ip-address "$START_IP_ADDRESS" \
  --end-ip-address "$END_IP_ADDRESS"

# Verify Firewall Rules
echo "Migration Successful !!"
echo "Check the firewall rules here : https://portal.azure.com/#resource/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.DBforMySQL/flexibleServers/$SERVER_NAME/networking"

MysqlVnetToPrivateEndpoint.sh

This script allows you to switch from using an integrated VNET to Private Link. This script detaches the VNET from the flexible server, disables public access, removes all delegations from the subnet, and then creates a private endpoint in the same subnet. Removing delegation from a subnet is a prerequisite to using it to create a private endpoint. Removing subnet delegation may fail if the subnet is still associated with another MySQL Flexible Server. The script also provides the option to access MySQL Flexible Server using the FQDN (e.g. myserver.mysql.database.azure.com) from inside the VNET by integrating with a private DNS zone.

#!/bin/bash
#
# PURPOSE
# Migrate Azure Database for MySQL Flexible Server from VNET Integrated to PrivateLink
# 
# DESCRIPTION
# Move from private access (virtual network integrated) to PrivateLink
# https://learn.microsoft.com/en-us/azure/mysql/flexible-server/how-to-network-from-private-to-public
#
# PREREQUISITES
# Azure CLI (https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)
# 
# ARGUMENTS
# --subscription-id -s                [Required] : Subscription ID.
# --resource-group-name -g            [Required] : Name of resource group.
# --server-name -n                    [Required] : Name of the server.
# --private-endpoint-name -r          [Required] : Name for the private endpoint.
# --integrate-private-dns-zone -z     [Optional] : Whether to integrate with a new Private DNS Zone.
#
# USAGE
# bash mysqlVnetToPrivateEndpoint.sh
#         --subscription-id 'ffffffff-ffff-ffff-ffff-ffffffffffff'
#         --resource-group-name 'mysqlRG'
#         --server-name 'mysqlflex'
#         --private-endpoint-name 'mysqlpe'
#         --integrate-private-dns-zone false
#

function usage()
{
    echo ""
    echo "PURPOSE"
    echo "Migrate Azure Database for MySQL Flexible Server from VNET Integrated to PrivateLink"
    echo ""
    echo "DESCRIPTION"
    echo "Move from private access (virtual network integrated) to PrivateLink"
    echo "https://learn.microsoft.com/en-us/azure/mysql/flexible-server/how-to-network-from-private-to-public"
    echo ""
    echo "PREREQUISITES"
    echo "Azure CLI (https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest)"
    echo ""
    echo "ARGUMENTS"
    echo " --subscription-id -s                [Required] : Subscription ID."
    echo " --resource-group-name -g            [Required] : Name of resource group."
    echo " --server-name -n                    [Required] : Name of the server."
    echo " --private-endpoint-name -r          [Required] : Name for the private endpoint."
    echo " --integrate-private-dns-zone -z     [Optional] : Whether to integrate with a new Private DNS Zone. Defaults to False"
    echo ""
    echo "USAGE"
    echo "bash mysqlVnetToPrivateEndpoint.sh"
    echo -e "\t--subscription-id 'ffffffff-ffff-ffff-ffff-ffffffffffff'"
    echo -e "\t--resource-group-name 'mysqlRG'"
    echo -e "\t--server-name 'mysqlflex'"
    echo -e "\t--private-endpoint-name 'mysqlpe'"
    echo -e "\t--integrate-private-dns-zone false"
    echo ""
    exit 1
}

PARAMS=""
while (( "$#" )); do
  case "$1" in
    -h| --help)
      usage
      exit
      ;;
    -s|--subscription-id)
      SUBSCRIPTION_ID=$2
      shift 2
      ;;
    -g|--resource-group-name)
      RESOURCE_GROUP_NAME=$2
      shift 2
      ;;
    -n|--server-name)
      SERVER_NAME=$2
      shift 2
      ;;
    -r|--private-endpoint-name)
      PRIVATE_ENDPOINT_NAME=$2
      shift 2
      ;;
    -z|--integrate-private-dns-zone)
      INTEGRATE_PRIVATE_DNS_ZONE=$2
      shift 2
      ;;
    --) # end argument parsing
      shift
      break
      ;;
    -*|--*=) # unsupported flags
      echo "Error: Unsupported flag $1" >&2
      exit 1
      ;;
    *) # preserve positional arguments
      PARAMS="$PARAMS $1"
      shift
      ;;
  esac
done
# set positional arguments in their proper place
eval set -- "$PARAMS"

# Ensure required parameters are provided
if [ -z "$SUBSCRIPTION_ID" ]; then
    echo "Error: Subscription ID is required"
    usage
fi

if [ -z "$RESOURCE_GROUP_NAME" ]; then
    echo "Error: Resource Group Name is required"
    usage
fi

if [ -z "$SERVER_NAME" ]; then
    echo "Error: Server Name is required"
    usage
fi

if [ -z "$PRIVATE_ENDPOINT_NAME" ]; then
    echo "Error: Private Endpoint Name is required"
    usage
fi

if [ -z "$INTEGRATE_PRIVATE_DNS_ZONE" ]; then
    INTEGRATE_PRIVATE_DNS_ZONE=false
else 
    if [ "$INTEGRATE_PRIVATE_DNS_ZONE" != "true" ] && [ "$INTEGRATE_PRIVATE_DNS_ZONE" != "false" ]; then
      echo "Error: --integrate-private-dns-zone must be either true or false"
      usage
    fi
fi

# Prerequisites - Install Azure CLI package
if ! [ -x "$(command -v az)" ]; then
  echo 'Error: azure cli is not installed. Please install from https://docs.microsoft.com/en-us/cli/azure/install-azure-cli?view=azure-cli-latest' >&2
  exit 1
fi

# Check if the subscription exists
if ! az account list --query "[?id=='$SUBSCRIPTION_ID' || name=='$SUBSCRIPTION_ID'].id" -o tsv | grep -q .; then
    echo "Subscription '$SUBSCRIPTION_ID' does not exist."
    exit 1
fi

# Set subscription
az account set --subscription "$SUBSCRIPTION_ID"

# Check if the resource group exists
if ! az group show --name "$RESOURCE_GROUP_NAME" > /dev/null 2>&1; then
    echo "Resource group '$RESOURCE_GROUP_NAME' does not exist."
    exit 1 
fi

# Check if the MySQL Flexible server exists
if ! az mysql flexible-server show --resource-group "$RESOURCE_GROUP_NAME" --name "$SERVER_NAME" > /dev/null 2>&1; then
    echo "MySQL Flexible Server '$SERVER_NAME' does not exist in resource group '$RESOURCE_GROUP_NAME'."
    exit 1
fi

# Get VNET and subnet details
echo "Obtaining Vnet and Subnet details for server $SERVER_NAME"
DELEGATED_SUBNET_RESOURCE_ID=$(az mysql flexible-server show --resource-group "$RESOURCE_GROUP_NAME" --name "$SERVER_NAME" --query "network.delegatedSubnetResourceId" --output tsv)

# Ensure server is VNET Integrated
if [ -z "$DELEGATED_SUBNET_RESOURCE_ID" ]; then
    echo "Error: MySQL Flexible Server is not VNET Integrated"
    exit 1
fi

# Extract VNET and Subnet details
VNET_SUB=$(echo $DELEGATED_SUBNET_RESOURCE_ID | cut -d "https://techcommunity.microsoft.com/" -f 3)
VNET_RG=$(echo $DELEGATED_SUBNET_RESOURCE_ID | cut -d "https://techcommunity.microsoft.com/" -f 5)
VNET=$(echo $DELEGATED_SUBNET_RESOURCE_ID | cut -d "https://techcommunity.microsoft.com/" -f 9)
SUBNET=$(echo $DELEGATED_SUBNET_RESOURCE_ID | cut -d "https://techcommunity.microsoft.com/" -f 11)

echo "VNET Subscription ID : $VNET_SUB"
echo "VNET Resource Group : $VNET_RG"
echo "VNET Name : $VNET"
echo "Subnet Name : $SUBNET"

echo "Detaching VNET $VNET from server $SERVER_NAME"
az mysql flexible-server detach-vnet --resource-group "$RESOURCE_GROUP_NAME"  --name "$SERVER_NAME" --public-network-access Disabled --yes

echo "Removing Delegations on Subnet $DELEGATED_SUBNET_RESOURCE_ID"
az network vnet subnet update --ids "$DELEGATED_SUBNET_RESOURCE_ID" --remove delegations

MYSQL_FLEX_RESOURCE_ID=$(az mysql flexible-server show --resource-group "$RESOURCE_GROUP_NAME" --name "$SERVER_NAME" --query "id" --output tsv)
MYSQL_FLEX_LOCATION=$(az mysql flexible-server show --resource-group "$RESOURCE_GROUP_NAME" --name "$SERVER_NAME" --query "location" --output tsv)

echo "Creating Private Endpoint $PRIVATE_ENDPOINT_NAME using Subnet $DELEGATED_SUBNET_RESOURCE_ID"
az network private-endpoint create \
  --resource-group "$VNET_RG" \
  --vnet-name "$VNET" \
  --subnet "$SUBNET" \
  --private-connection-resource-id "$MYSQL_FLEX_RESOURCE_ID" \
  --group-id mysqlServer \
  --connection-name "$PRIVATE_ENDPOINT_NAME" \
  --name "$PRIVATE_ENDPOINT_NAME" \
  --location "$MYSQL_FLEX_LOCATION"

if [ "$INTEGRATE_PRIVATE_DNS_ZONE" == "true" ]; then
  echo "Creating Private DNS Zone"
  az network private-dns zone create \
      --resource-group "$VNET_RG" \
      --name "privatelink.mysql.database.azure.com"

  echo "Linking Private DNS Zone with VNET $VNET"
  az network private-dns link vnet create \
      --resource-group "$VNET_RG" \
      --zone-name "privatelink.mysql.database.azure.com" \
      --name "${VNET}Link" \
      --virtual-network "$VNET" \
      --registration-enabled false

  echo "Creating Private DNS Zone Group"
  az network private-endpoint dns-zone-group create \
    --resource-group "$VNET_RG" \
    --endpoint-name "$PRIVATE_ENDPOINT_NAME" \
    --name "${PRIVATE_ENDPOINT_NAME}ZoneGroup" \
    --private-dns-zone "privatelink.mysql.database.azure.com" \
    --zone-name mysqlServer
fi   

# Verify Private Endpoints
echo "Migration Successful !!"
echo "Check the private endpoints here : https://portal.azure.com/#resource/subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME/providers/Microsoft.DBforMySQL/flexibleServers/$SERVER_NAME/networking"

Try it out!

We encourage you to try out these scripts to help streamline your conversion process. You can download it from the following GitHub repository folder: azure/azure-mysql/script

If you have any questions or suggestions, please let us know by leaving a comment below or contacting us directly at: AskAzureDBforMySQL@service.microsoft.com.





Source link

You may also like

Leave a Comment

Our Company

Welcome to OdysseyX, your one-stop destination for the latest news and opportunities across various domains.

Newsletter

Subscribe my Newsletter for new blog posts, tips & new photos. Let's stay updated!

Laest News

@2024 – All Right Reserved. Designed and Developed by OdysseyX