Comment utiliser le provider alias pour le déploiement de spoke ?

Une topologie Hub-and-Spoke est un modèle de réseau en étoile qui permet d’isoler des charges de travail tout en partageant des services communs. Dans cet article, nous allons nous pencher sur l’utilisation de l’alias de provider de terraform pour déployer une topologie Hub and Spoke dans Azure.

Concepts de l’architecture hub and spoke dans Azure

Lorsque l’on parle des fondations Azure IaaS, l’architecture de référence mise en avant par Microsoft est l’architecture Hub and Spoke. Les concepts de cette architecture sont relativement simples. Dans la majorité des organisations IT, l’objectif est « d’hybridifier » le datacenter mettant en place une interconnexion entre celui-ci et un environnement Cloud.  Une architecture Hub and Spoke ressemble à ceci :

Le concept de base de cette topologie est de minimiser l’impact du cout de l’interconnexion (VPN ou ExpressRoute) entre Azure et le réseau On-premise en connectant un unique VNet, appelé VNet Hub avec celui-ci. Les VNets portant les environnements applicatifs sont appelés VNet spoke et sont connectés vers le hub au moyen de connexions dites de peering, reposant sur le backbone réseau d’Azure et ne souffrant pas d’une part de latence réseau importante, et d’autre part, générant un coût très inférieur à la gestion de multiples interconnexions avec le réseau on-premise.

Les raisons de la mise en avant de cette architecture sont à la fois des raisons techniques et des raisons de gouvernance.

D’un point de vue technique, rappelons les faits suivants :

  • Un VNet a un certain nombre de limites, comme le nombre d’adresses IP Privées disponibles. En effet, il n’est possible d’avoir « que » 65535 adresses, c’est-à-dire un /16 en notation CIDR, dans un VNet. Bien qu’étant un nombre important, le design des sous-réseaux peut rapidement engendrer la consommation de ces adresses, d’autant qu’un sous-réseau dans Azure consomme non pas 2 (Network address & broadcast address) mais 5 IPs.
  • Il y a également des limites en termes de nombre de ressources déployables dans une souscription. Les informations sur ces limites sont maintenues par Microsoft sur la page Azure subscription limits.
  • D’un point de vue gouvernance, il est important de considérer la connexion réseau depuis le site on-premise. Malgré le paradigme Self-service du Cloud, il est extrêmement rare d’avoir la possibilité pour n’importe quelle population d’implémenter un lien réseau depuis des ressources privées du datacenter vers un environnement externe comme un cloud public. En dehors du cout associé à ce genre de lien, cela va à l’encontre des pratiques de sécurités existante dans tous les départements IT.

Dans cette logique, un VNet Hub géré par les équipes IT et interconnecté d’un point de vue réseau avec le datacenter d’un côté, et les VNets des différents consommateurs de ressources Cloud constitue un meilleur scénario. Effectivement, le contrôle de la connexion vers le Datacenter reste limité en termes de population, et la gestion des autres ressources Cloud peut etre déléguée aux consommateurs de ces ressources, moyennant un certain nombre de règles d’utilisations.

Voilà en résumé très sommaire les arguments allant en faveur du modèle Hub and Spoke. A présent, penchons-nous sur les impacts de ce modèle.

L’impact du modèle Hub and Spoke sur la gouvernance

Résumons la situation, nous avons potentiellement autant de VNets à déployer que de projets, et ces VNets doivent être connectés au VNet Hub par le biais de VNet Peering.

D’un point de vue technique, un VNet Peering est un objet qui existe pour chacun des 2 VNets qui sont connectés ensemble. Ce qui veut dire que nous devons donc les implémenter dans chacun des 2 VNets.

Si l’on considère un scénario ou les propriétaires du VNet Hub sont différents des propriétaires du VNet Spoke, il est nécessaire d’être en mesure d’accéder aux 2 VNets pour créer les objets VNet Peering requis.

De façon non automatique, cela n’est pas un challenge en soit, à travers le portail ou un appel d’API quelconque.

Mais qu’en est il de l’automatisation ou de l’intégration dans une chaine CI/CD ?

Le cas du déploiement avec terraform

Rappel sur la configuration du provider terraform

 

Avec Terraform, une souscription est ciblée pour y déployer des ressources. Le provider azurerm est utilisé comme ci-après :

provider "azurerm" {
  subscription_id = var.AzureSubscriptionID
  client_id       = var.AzureClientID
  client_secret   = var.AzureClientSecret
  tenant_id       = var.AzureTenantID
}

Dans cet exemple, nous utilisons des variables pour définir le provider. Il est également possible de réaliser l’authentification à l’aide de AZ Cli, en sélectionnant la souscription cible :

PS C:\Users\User1\> az account set --subscription xxxx-xxxx-…
PS C:\Users\User1\> az account list --output table
Name              CloudName         SubscriptionId    State       IsDefault
----              ---------         --------------    -------        ---------
Project02-(PAYG)  AzureCloud        xxxx-xxxx-…       Enabled        False
OCP-Payasyougo    AzureCloud        xxxx-xxxx-…       Enabled        False
Sponsorship DFR   AzureCloud        xxxx-xxxx-…       Enabled        True
MSDN DFR          AzureCloud        xxxx-xxxx-…       Enabled        False

Dans l’exemple précédent, après avoir sélectionné la souscription cible avec la commande az account set, il est possible de vérifier que celle-ci est bien ciblée en utilisant la commande az account list. La souscription cible apparait avec une valeur True pour IsDefault. Cependant, nous restons limités dans ces 2 cas à une seule souscription cible à la fois. Un moyen de contourner cette limite est l’utilisation du provider alias. Regardons comment cela fonctionne.

Le Provider alias

Comme nous l’avons dit précédemment, nous définissons le provider de la manière suivante :

provider "azurerm" {
  subscription_id = var.AzureSubscriptionID
  client_id       = var.AzureClientID
  client_secret   = var.AzureClientSecret
  tenant_id       = var.AzureTenantID
}

Il est possible d’avoir plusieurs providers ciblant différent système/cloud, comme par exemple une souscription Azure et un cluster Kubernetes qui seraient déployés dans cette même souscription. Cependant, il n’est pas aisé d’envisager de cibler 2 systèmes identiques dans la même configuration. C’est ici qu’entre en scène le provider alias. En ajoutant le paramètre alias dans la configuration du provider, nous sommes en mesure de cibler une autre souscription Azure dans la même configuration terraform :

provider "azurerm" {
  subscription_id = var.AzureSubscriptionID2
  client_id       = var.AzureClientID
  client_secret   = var.AzureClientSecret
  tenant_id       = var.AzureTenantID
  alias           = "SpokeSub"
}

Il est important de noter que nous déclarons ici un id de souscription différent. Les clients ids, clients secrets peuvent être identiques ou différents, selon la manière donc la configuration IAM est réalisée. Le tenant Id fait référence au tenant Azure AD et on va en général avoir le même pour toutes les souscriptions.

Une fois ce provider alias déclaré, nous pouvons spécifier celui-ci dans la création de ressource comme affiché ci-après :

module "Spoke1" {
  #Module Location
  source = "./Modules/Spoke/"
  #Module Provider
  providers = {
    azurerm = azurerm.SpokeSub
  }
  #Module variable
  …
}

Utiliser le provider alias pour le déploiement Hub and Spoke

A présent que les détails de configuration ont été spécifiés, revenons à notre scénario de déploiement Hub and Spoke. Nous souhaitons déployer un VNet Hub dans une souscription et un VNet Spoke dans une autre souscription. Nous aurons également besoin de créer les objets VNet Peering dans chacune des souscriptions.

Déploiement des VNets

 

Prenons l’hypothèse que nous avons un module pour déployer nos VNet Hub and Spoke. Pour le VNet Hub, nous utilisons le provider azurerm par défaut et pour le VNet spoke, nous utilisons le provider azurerm pointant vers la souscription cible du spoke, identifiée par l’alias SpokeSub.

Pour le module du VNet Hub, aucun ajout d’alias n’est requis, et pour le VNet Spoke, nous spécifions le provider souhaité :

module "HubInfra" {
  #Module Location
  source = "./Modules/hub/"
  #Module variable
  …
}


module "Spoke1" {
  #Module Location
  source = "./Modules/Spoke/"
  #Module Provider
  providers = {
    azurerm = azurerm.SpokeSub
  }
  #Module variable
  …
}

Déploiement des VNet peerings

 

Concernant les objets VNet Peering, nous déclarons le code suivant :

module "Peering_VNetHub_To_Spoke1" {
#Module location
  source = "./Modules/peering"

  #Module variable
  VNetPeeringName                   = "Peering_VNetHub_To_Spoke1"
  RGName                            = data.azurerm_resource_group.RGHub.name
  LocalVNetName                     = data.azurerm_virtual_network.VNetHub.name
  RemoteVNetId                      = module.Spoke1.VNetSpokeId
  IsVirtualNetworkAcccessAllowed    = "true"
  IsForwardedTrafficAllowed         = "true"
  IsGWTransitAllowed                = "true"
}
module "Peering_Spoke1_To_VNetHub" {
#Module location
  source = "./Modules/peering"
  #Module Provider
  providers = {
    azurerm = azurerm.SpokeSub
  }
  #Module variable
  VNetPeeringName                   = "Peering_Spoke1_To_VNetHub"
  RGName                            = module.Spoke1.RGSpokeName
  LocalVNetName                     = module.Spoke1.VNetspokeName
  RemoteVNetId                      = data.azurerm_virtual_network.VNetHub.id
  IsVirtualNetworkAcccessAllowed    = "true"
  IsForwardedTrafficAllowed         = "true"
  UseRemoteGW                       = "true"
}

Nous spécifions l’alias provider pour le VNet Peering du côté du spoke, et nous utilisons les outputs de module pour faire références aux Id de ressources des VNets.

Enfin, nous devons aussi spécifier quelques autres paramètres qui vont définir le comportement de notre peering.

Considérations de déploiement à propos du réseau dans Azure

 

Lorsqu’un peering est créé, cela revient à connecter 2 VNet ensemble qui se comporteront comme un VNet unique. Une fois que le peering est créé, le trafic est routé entre les subnets de chacun des VNets. Techniquement, le service tag VNet dans les règles de NSG définira l’espace d’adressage des 2 VNets en peering, en respect toutefois, de la propriété non transitive des VNets peering.

Cela dit, nous pouvons configurer dans le peering la façon dont le flux réseau circule de la manière ci-après :

Comme l’illustre les 2 captures d’écran, il est possible d’activer ou non le trafic entre les VNets et d’autoriser ou non le trafic forwarding entre VNets.

Également, à propos d’une éventuelle connexion vers un site on premise, nous pouvons définir si la Virtual network Gateway autorisera ou non le trafic provenant du VNet spoke en peering, et du point de vue du VNet spoke, si l’on autorisera ou non l’utilisation de la Virtual network Gateway du hub, désignée par l’item Remote Gateway.

D’un point de vue terraform, cela correspond à ces paramètres dans le VNet Hub :

  IsVirtualNetworkAcccessAllowed    = "true"
  IsForwardedTrafficAllowed         = "true"
  IsGWTransitAllowed                = "true"

Et dans le VNet Spoke

  IsVirtualNetworkAcccessAllowed    = "true"
  IsForwardedTrafficAllowed         = "true"
  UseRemoteGW                       = "true"

Conclusion

Dans cet article, nous avons exploré les bénéfices du provider alias pour permettre le déploiement d’une topologie Azure Hub and Spoke.

La disponibilité de cette fonctionnalité est un énorme avantage pour la gestion du déploiement de ressources à travers plusieurs souscriptions.

Il y a sans aucun doute d’autres applications de cette fonctionnalité, de même que d’autres considérations à prendre en compte pour l’automatisation complète d’une topologie Hub and Spoke.

Dans de prochains articles probablement !

devoteam

Contact

David Frappart

Architecte Cloud
MVP Azure