Saturday, April 11, 2026

 This is a runbook for migrating a set of microservices in the form of a UI and many APIs from one region to another

1. Step 1. Create all the containers in the destination.

#!/usr/bin/env bash

set -euo pipefail

# -----------------------------

# CONFIGURATION

# -----------------------------

SOURCE_RG="rg-microservices"

DEST_SUFFIX="eus2"

DEST_LOCATION="eastus2"

DEST_RG="${SOURCE_RG}-${DEST_SUFFIX}"

echo "Source RG: ${SOURCE_RG}"

echo "Destination RG: ${DEST_RG}"

echo "Destination Region: ${DEST_LOCATION}"

echo ""

# -----------------------------

# CREATE DESTINATION RG

# -----------------------------

echo "Creating destination resource group..."

az group create \

  --name "${DEST_RG}" \

  --location "${DEST_LOCATION}" \

  --output none

echo "Destination RG created."

echo ""

# -----------------------------

# ENUMERATE RESOURCES

# -----------------------------

echo "Enumerating resources in ${SOURCE_RG}..."

RESOURCE_IDS=$(az resource list -g "${SOURCE_RG}" --query "[].id" -o tsv)

if [[ -z "${RESOURCE_IDS}" ]]; then

  echo "No resources found in ${SOURCE_RG}"

  exit 1

fi

echo "Found resources:"

echo "${RESOURCE_IDS}"

echo ""

# -----------------------------

# EXPORT EACH RESOURCE WITH aztfexport

# -----------------------------

EXPORT_DIR="./export-${SOURCE_RG}-${DEST_SUFFIX}"

mkdir -p "${EXPORT_DIR}"

for RID in ${RESOURCE_IDS}; do

  NAME=$(basename "${RID}")

  NEW_NAME="${NAME}-${DEST_SUFFIX}"

  echo "Exporting resource:"

  echo " Source ID: ${RID}"

  echo " New Name: ${NEW_NAME}"

  echo ""

  aztfexport resource \

    --resource "${RID}" \

    --resource-group "${DEST_RG}" \

    --location "${DEST_LOCATION}" \

    --name-mapping "${NAME}=${NEW_NAME}" \

    --output-directory "${EXPORT_DIR}" \

    --append

done

echo ""

echo "----------------------------------------"

echo "Export completed. Terraform files stored in:"

echo " ${EXPORT_DIR}"

echo "----------------------------------------"

2. Step 2. Copy all the configurations for each web service.

#!/usr/bin/env bash

set -euo pipefail

SOURCE_RG="rg-microservices"

DEST_SUFFIX="eus2"

DEST_RG="${SOURCE_RG}-${DEST_SUFFIX}"

echo "Source RG: ${SOURCE_RG}"

echo "Destination RG: ${DEST_RG}"

echo ""

# ---------------------------------------------

# ENUMERATE ALL WEB APPS IN SOURCE RG

# ---------------------------------------------

echo "Enumerating Web Apps in ${SOURCE_RG}..."

APPS=$(az webapp list -g "${SOURCE_RG}" --query "[].name" -o tsv)

if [[ -z "${APPS}" ]]; then

  echo "No Web Apps found in ${SOURCE_RG}"

  exit 1

fi

echo "Found Web Apps:"

echo "${APPS}"

echo ""

# ---------------------------------------------

# COPY CONFIG FOR EACH APP

# ---------------------------------------------

for APP in ${APPS}; do

  DEST_APP="${APP}-${DEST_SUFFIX}"

  echo "---------------------------------------------"

  echo "Copying configuration:"

  echo " Source: ${APP}"

  echo " Dest: ${DEST_APP}"

  echo "---------------------------------------------"

  # -----------------------------

  # GET SOURCE CONFIG

  # -----------------------------

  CONFIG=$(az webapp config show -g "${SOURCE_RG}" -n "${APP}")

  KIND=$(echo "${CONFIG}" | jq -r '.kind')

  LINUX_FX=$(echo "${CONFIG}" | jq -r '.linuxFxVersion')

  WINDOWS_FX=$(echo "${CONFIG}" | jq -r '.windowsFxVersion')

  STARTUP_CMD=$(echo "${CONFIG}" | jq -r '.appCommandLine')

  # -----------------------------

  # COPY RUNTIME STACK

  # -----------------------------

  if [[ "${LINUX_FX}" != "null" && "${LINUX_FX}" != "" ]]; then

    echo "Applying Linux runtime stack: ${LINUX_FX}"

    az webapp config set \

      -g "${DEST_RG}" \

      -n "${DEST_APP}" \

      --linux-fx-version "${LINUX_FX}" \

      --startup-file "${STARTUP_CMD}" \

      --output none

  fi

  if [[ "${WINDOWS_FX}" != "null" && "${WINDOWS_FX}" != "" ]]; then

    echo "Applying Windows runtime stack: ${WINDOWS_FX}"

    az webapp config set \

      -g "${DEST_RG}" \

      -n "${DEST_APP}" \

      --windows-fx-version "${WINDOWS_FX}" \

      --output none

  fi

  # -----------------------------

  # COPY APP SETTINGS

  # -----------------------------

  echo "Copying app settings..."

  az webapp config appsettings list \

    -g "${SOURCE_RG}" \

    -n "${APP}" \

    | jq -r '.[] | "\(.name)=\(.value)"' \

    > /tmp/appsettings.txt

  if [[ -s /tmp/appsettings.txt ]]; then

    az webapp config appsettings set \

      -g "${DEST_RG}" \

      -n "${DEST_APP}" \

      --settings $(cat /tmp/appsettings.txt) \

      --output none

  fi

  # -----------------------------

  # COPY CONTAINER SETTINGS (IF ANY)

  # -----------------------------

  if [[ "${LINUX_FX}" == *"DOCKER"* ]]; then

    echo "Detected container-based app. Copying container settings..."

    IMAGE=$(echo "${LINUX_FX}" | sed 's/DOCKER|//')

    REGISTRY=$(az webapp config container show -g "${SOURCE_RG}" -n "${APP}")

    SERVER=$(echo "${REGISTRY}" | jq -r '.dockerRegistryServerUrl')

    USER=$(echo "${REGISTRY}" | jq -r '.dockerRegistryServerUserName')

    PASS=$(echo "${REGISTRY}" | jq -r '.dockerRegistryServerPassword')

    az webapp config container set \

      -g "${DEST_RG}" \

      -n "${DEST_APP}" \

      --docker-custom-image-name "${IMAGE}" \

      --docker-registry-server-url "${SERVER}" \

      --docker-registry-server-user "${USER}" \

      --docker-registry-server-password "${PASS}" \

      --output none

  fi

  echo "Completed configuration copy for ${APP} → ${DEST_APP}"

  echo ""

done

echo "---------------------------------------------"

echo "All Web App configurations copied successfully."

echo "---------------------------------------------"

3. Step 3. Repoint the dns alias, certificates and deploy images

#!/usr/bin/env bash

set -euo pipefail

SOURCE_RG="rg-microservices"

DEST_SUFFIX="eus2"

DEST_RG="${SOURCE_RG}-${DEST_SUFFIX}"

# DNS zone (example: example.com)

DNS_ZONE_RG="rg-dns"

DNS_ZONE_NAME="example.com"

echo "Source RG: ${SOURCE_RG}"

echo "Destination RG: ${DEST_RG}"

echo "DNS Zone: ${DNS_ZONE_NAME}"

echo ""

# ---------------------------------------------

# ENUMERATE ALL WEB APPS IN SOURCE RG

# ---------------------------------------------

echo "Enumerating Web Apps in ${SOURCE_RG}..."

APPS=$(az webapp list -g "${SOURCE_RG}" --query "[].name" -o tsv)

if [[ -z "${APPS}" ]]; then

  echo "No Web Apps found in ${SOURCE_RG}"

  exit 1

fi

echo "Found Web Apps:"

echo "${APPS}"

echo ""

# ---------------------------------------------

# PROCESS EACH APP

# ---------------------------------------------

for APP in ${APPS}; do

  DEST_APP="${APP}-${DEST_SUFFIX}"

  echo "---------------------------------------------"

  echo "Repointing DNS:"

  echo " Source App: ${APP}"

  echo " Dest App: ${DEST_APP}"

  echo "---------------------------------------------"

  # Get default hostnames

  SRC_HOST="${APP}.azurewebsites.net"

  DEST_HOST="${DEST_APP}.azurewebsites.net"

  # Get custom hostnames bound to the source app

  HOSTNAMES=$(az webapp config hostname list \

    -g "${SOURCE_RG}" \

    -n "${APP}" \

    --query "[].name" -o tsv)

  if [[ -z "${HOSTNAMES}" ]]; then

    echo "No custom hostnames found for ${APP}"

    continue

  fi

  echo "Custom hostnames:"

  echo "${HOSTNAMES}"

  echo ""

  # ---------------------------------------------

  # UPDATE DNS CNAME RECORDS

  # ---------------------------------------------

  for HOST in ${HOSTNAMES}; do

    # Extract the relative record name (e.g., api.example.com → api)

    RECORD_NAME=$(echo "${HOST}" | sed "s/.${DNS_ZONE_NAME}//")

    echo "Updating DNS CNAME:"

    echo " Host: ${HOST}"

    echo " Record name: ${RECORD_NAME}"

    echo " New target: ${DEST_HOST}"

    # Create or update the CNAME record

    az network dns record-set cname set-record \

      --resource-group "${DNS_ZONE_RG}" \

      --zone-name "${DNS_ZONE_NAME}" \

      --record-set-name "${RECORD_NAME}" \

      --cname "${DEST_HOST}" \

      --output none

    echo "DNS updated: ${HOST} → ${DEST_HOST}"

    echo ""

  done

done

echo "---------------------------------------------"

echo "All DNS aliases repointed successfully."

echo "---------------------------------------------"


#Codingexercise: https://1drv.ms/w/c/d609fb70e39b65c8/IQBsEmahUOniS6mjF1KpHShiAXrShCZDA26CITHTjDsJzp4?e=CTKIwy


No comments:

Post a Comment