Azure API Management stv1 to stv2 migration using terraform

This post has been republished via RSS; it originally appeared at: Microsoft Tech Community - Latest Blogs - .

Migrating an Azure API Management (APIM) instance from the stv1 platform to the stv2 platform involves updating the underlying compute while preserving the service/API configuration stored in the storage layer. The publications below outline the migration dynamics and the strategies, depending on the configuration of the service:
In this article we will discuss how migration can be achieved using terraform.
 
Migrating non-vnet injected instances:
 
For non-vnet injected instances the migration needs to be triggered from the portal or using the REST API. This will not impact the terraform state and there is no need to alter any terraform code if the preserve ip option is used for migration.
 
Migrating vnet injected instances:
 
For vnet injected instances, the migration trigger is assigning a publicip and a new subnet as describe below:
 
# STV2 MIGRATION: New public ip in the same region and subscription, standard sku with a DNS label
resource "azurerm_public_ip" "apim_mgmt_public_ip" {
  name = local.public_ip_address_name_apim
  location = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  sku = "Standard"
  sku_tier = "Regional"
  allocation_method = "Static"
  ip_version = "IPv4"
  # STV2 MIGRATION: Required dns label
  domain_name_label = "apim${random_string.azurerm_api_management_name.result}"
}

# STV2 MIGRATION: NSG should have all the rules required for stv2
# This illustration is for internal network model. Refer https://learn.microsoft.com/en-us/azure/api-management/api-management-using-with-internal-vnet?tabs=stv2#configure-nsg-rules
resource "azurerm_network_security_group" "apim_snnsg_nsg_new" {
name = local.apim_snnsg_new
  location = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  
  security_rule {
    name = "AllowApimVnetInbound"
    priority = 2000
    protocol = "Tcp"
    destination_port_range = "3443"
    access = "Allow"
    direction = "Inbound"
    source_port_range = "*"
    source_address_prefix = "ApiManagement"
    destination_address_prefix = "VirtualNetwork"
  }
  
  security_rule {
    name = "apim-azure-infra-lb"
    priority = 2010
    protocol = "Tcp"
    destination_port_range = "6390"
    access = "Allow"
    direction = "Inbound"
    source_port_range = "*"
    source_address_prefix = "AzureLoadBalancer"
    destination_address_prefix = "VirtualNetwork"
  }
  
  security_rule {
    name = "apim-azure-storage"
    priority = 2000
    protocol = "Tcp"
    destination_port_range = "443"
    access = "Allow"
    direction = "Outbound"
    source_port_range = "*"
    source_address_prefix = "VirtualNetwork"
    destination_address_prefix = "Storage"
  }
  
  security_rule {
    name = "apim-azure-sql"
    priority = 2010
    protocol = "Tcp"
    destination_port_range = "1443"
    access = "Allow"
    direction = "Outbound"
    source_port_range = "*"
    source_address_prefix = "VirtualNetwork"
    destination_address_prefix = "SQL"
  }
  
  security_rule {
    name = "apim-azure-kv"
    priority = 2020
    protocol = "Tcp"
    destination_port_range = "443"
    access = "Allow"
    direction = "Outbound"
    source_port_range = "*"
    source_address_prefix = "VirtualNetwork"
    destination_address_prefix = "AzureKeyVault"
  }
}

resource "azurerm_virtual_network" "apim_vnet" {
  name = "vnet${random_string.azurerm_vnet_name.result}"
  location = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  address_space = [var.apim_vnet_name_address_prefix]

  .....
  .....
  .....
      
  # STV2 MIGRATION: New subnet in the same vnet or a different vnet in the same region
  subnet {
    name = local.apim_subnet_name_new
    address_prefix = local.apim_address_prefix_new
    # STV2 MIGRATION: NSG should have all the rules for stv2
    security_group = azurerm_network_security_group.apim_snnsg_nsg_new.id
    # STV2 MIGRATION: required when using a UDR to force tunnel traffic 
    # service_endpoints =
  }
}

# STV2 MIGRATION: UDR to be attached if required to force tunnel
# resource "azurerm_subnet_route_table_association" "example" {
  # subnet_id = azurerm_subnet.example.id
  # route_table_id = azurerm_route_table.example.id
#}

resource "azurerm_api_management" "api" {
  name = "apiservice${random_string.azurerm_api_management_name.result}"
  location = azurerm_resource_group.rg.location

  .....
  .....
  .....
  
  # STV2 MIGRATION: public ip is required to migrate to stv2
  public_ip_address_id = azurerm_public_ip.apim_mgmt_public_ip.id
  
  virtual_network_configuration {
    # STV2 MIGRATION: change the subnet to a new one
    subnet_id = "${azurerm_virtual_network.apim_vnet.id}/subnets/${local.apim_subnet_name_new}"
  }
}

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.