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 !