Confidentialité basée sur l'équipe avec IAM, VPC, Transit Gateway et DNS

Ce tutoriel peut entraîner des coûts. Utilisez l'Estimateur de coûts pour générer une estimation du coût en fonction de votre utilisation projetée.

Les microservices sont populaires parce qu'ils permettent à une entreprise d'organiser ses équipes de développement autour des services qu'elle propose. Ce tutoriel vous guide à travers les étapes de la création d'une infrastructure pour une IBM Cloud® Virtual Private Cloud (VPC) basée sur une architecture de microservices. Dans cette architecture, les clouds privés virtuels (VCP) sont connectés les uns aux autres à l'aide de l'IBM Cloud® Transit Gateway. L'accès à un ensemble de microservices partagés se fait par l'intermédiaire de noms d'hôtes enregistrés dans le IBM Cloud® DNS Services Chaque VPC est géré par une équipe distincte isolée par IBM Cloud® Identity and Access Management. En option, un IBM Cloud® Load Balancer peut être utilisé pour étendre le microservice partagé.

Objectifs

  • Apprendre à isoler l'infrastructure via IAM et les groupes de ressources
  • Créer les VPC et des ressources associées telles que des sous-réseaux, ACL réseau, groupes de sécurité et instances.
  • Adresser les microservices par résolution de nom DNS en utilisant DNS Services
  • Connecter des VPC via Transit Gateway.
  • Configurer de manière transparente Load Balancer pour une application.

Architecture abstraite

Architecture*Diagramme d'
du

Dans le diagramme ci-dessus, l'utilisateur final accède aux applications. Les applications s'appuient sur des microservices partagés. La société dispose d'équipes DevOps distinctes possédant application1, application2 et shared. Une équipe network (réseau) se concentre sur la connectivité et la sécurité du réseau. Les équipes DevOps gèrent les instances de service virtuel (VSI) utilisées pour mettre en oeuvre les services qu'elles créent et prennent en charge.

Architecture concrète

L'architecture suivante implémente les exigences en matière d'isolement et de connectivité définies par la société. Notez que application1, shared et application2 sont des VPC. Les sous-réseau et zone uniques de chaque VPC peuvent être étendus à une implémentation multizone détaillée au fil du temps.

Architecture du tutoriel
Architecture du tutoriel

Avant de commencer

Pour ce tutoriel, vous devez disposer des éléments suivants :

  • Interface de ligne de commande IBM Cloud avec les plug-in suivants:
    • Transit Gateway (tg)
    • IBM Cloud VPC (vpc-infrastructure)
    • DNS Services (dns)
  • de git pour cloner le référentiel de code source.
  • de terraform pour exécuter les commandes Terraform.

Vous trouverez les instructions pour télécharger et installer ces outils pour votre environnement d'exploitation dans le guide " Getting started with solution tutorials ".

De plus :

  • Vérifiez les autorisations d'utilisateur. Assurez-vous que votre compte d'utilisateur dispose des droits suffisants pour créer et gérer des ressources VPC, créer une passerelle IBM Cloud® Transit Gateway et des services IBM Cloud® Transit Gateway. Consultez la liste des autorisations requises pour VPC. Vous devrez également être capable de créer des groupes de ressources et des ressources IAM telles que des groupes d'accès, des politiques, des identifiants de service, ...
  • Une clé SSH est nécessaire pour la connexion aux serveurs virtuels. Si vous n'avez pas de clé SSH, reportez-vous aux instructions afin d'en créer une pour VPC.

Planification de l'environnement pour IAM (Identity and Access Management)

L'équipe d'administrateurs va permettre aux autres équipes d'administrer leurs ressources autant que possible. L'équipe d'administrateurs gérera les utilisateurs et le contrôle d'accès mais ne créera pas et ne détruira pas les ressources affichées dans le diagramme d'architecture.

Editeur, Opérateur, Afficheur et Gestionnaire sont des rôles d'accès IAM. Chaque service définit le sens exacte des rôles et leurs actions associées.

Equipes :

  • Admin - définir la structure de compte comme les groupes de ressources, les utilisateurs et les rôles
  • Réseau-créer des ressources réseau telles que DNS Services, Transit Gateway service, VPC et des sous-réseaux.
  • Shared - créer l'instance VSI et les unités par bloc dans le VPC partagé. Créer des enregistrements DNS pour les services partagés.
  • Application1 - créer l'instance VSI et les unités par bloc dans le VPC application1.
  • Application2 - créer l'instance VSI et les unités par bloc dans le VPC application2.

IAM conceptuel

Equipe Network

Une modèle de propriété d'équipe conceptuelle a été implémentée. L'équipe network administre toutes les ressources réseau et, par conséquent, la plupart des éléments affichés dans le diagramme.

Architecture axée sur l'équipe réseau
Architecture axée sur l'équipe réseau

Equipe Shared

L'équipe shared (partagée) crée l'instance VSI dans son VPC isolé. En outre, l'équipe doit écrire des enregistrements dans le service DNS puisque les adresses IP des VSI sont déterminées au moment de la création. L'accès opérateur aux VPC, sous-réseaux et groupes de sécurité sont obligatoire pour créer une instance VSI.

Architecture axée sur l'équipe partagée
Architecture axée sur l'équipe partagée

Les équipes de l' application ont besoin du même accès que l'équipe partagée, à l'exception de l'accès du gestionnaire à DNS Services.

Accès de l'équipe Application :

Architecture axée sur l'équipe d'application
Architecture axée sur l'équipe d'application

Architecture IAM

Si vous avez une bonne compréhension des groupes de ressources et des groupes d'accès IAM, vous pouvez rapidement parcourir cette section et démarrer la procédure de création des ressources.

Groupes d'accès

Un groupe d'accès est créé pour chaque équipe. Des règles d'accès sont ajoutées aux groupes d'accès, puis les utilisateurs (membres d'équipe) sont ajoutés au groupe d'accès pour accorder l'accès.

L'instance de service Transit Gateway est gérée exclusivement par l'équipe network. Un accès Editeur est requis pour la création. L'accès Gestionnaire à l'instance créée permet aux VPC d'être connectés au Transit Gateway.

Dans cet exemple, une seule zone DNS, widgets.example.com, sera créée et l'accès à la zone DNS sera autorisé à tous les VPC. L'instance de service DNS est créée par l'équipe network (rôle Editeur) et l'autorisation des zones requiert le rôle Gestionnaire. La résolution DNS lors de l'exécution d'une instance sur un VPC ne nécessite pas l'accès IAM. L'équipe Partagé doit répertorier les instances DNS (rôle de l'afficheur) et ajouter un enregistrement A ou CNAME (rôle de gestionnaire).

Le service d'infrastructure (IS) VPC se compose d'une quinzaine de types de service différents. Certaines ne concernent que l'équipe réseau, comme les ACL (listes de contrôle d'accès). D'autres ne concernent que les équipes de microservices, comme les instances VSI. Mais certains sont édités par l'équipe réseau et exploités par l'équipe microservices, comme les sous-réseaux. L'équipe réseau créera le sous-réseau et l'équipe microservice créera une instance dans un sous-réseau. Pour les besoins de ce tutoriel, les types de service VPC IS, Transit Gateway et le DNS sont récapitulés pour chaque groupe d'accès dans le tableau ci-dessous. Ce dernier contient les rôles requis.

Rôles requis affectés aux équipes en fonction de leurs responsabilités
Service réseau shared application
Transit Gateway Éditeur, Responsable
DNS Éditeur, Responsable Afficheur, gestionnaire
IS : ACL de réseau Editeur
IS : Instance, Volume, IP flottante, Clé SSH, Image, Equilibreur de charge Editeur Editeur
IS : VPC, Sous-réseau, Groupe de sécurité Editeur Opérateur Opérateur

Groupes de ressources

L'équipe shared et l'équipe network sont maintenant bien distinctes. Mais comment Application1 est-elle isolée de Shared et Application2 ? Elles sont Editeur pour les mêmes types de service.

C'est la que les groupes de ressources interviennent. Chaque instance de service (c'est-à-dire ressource) possède un attribut de groupe de ressources qui est initialisé lors de la création et ne peut être modifié. En d'autres termes, chaque ressource fait partie d'un groupe de ressources.

Diagramme du groupe de ressources :

Diagramme de groupe de ressources
Diagramme de groupe de ressources

Chaque équipe de microservice sera autorisée à accéder au groupe de ressources correspondant. L'équipe réseau aura accès à tous ces groupes de ressources.

Le groupe de ressources réseau contient Transit Gateway et le service DNS. L'équipe réseau a accès à ces ressources. L'équipe partagée aura un accès de gestionnaire au service DNS. L'équipe partagée doit écrire les entrées DNS pour les services partagés.

Plus tard dans le tutoriel, après que toutes les ressources aient été créées, il peut être informatif d'ouvrir la liste des ressources dans la console IBM Cloud. Il est possible d'appliquer un filtre au groupe de ressources.

Création d'un environnement de travail local

Toutes les opérations seront effectuées dans un shell bash et en utilisant les commandes terraform et ibmcloud. Vous trouverez les instructions pour télécharger et installer ces outils pour votre environnement d'exploitation dans le guide " Getting started with solution tutorials ".

  1. Git clone le référentiel suivant:

    git clone https://github.com/IBM-Cloud/vpc-tg-dns-iam
    cd vpc-tg-dns-iam
    

    Vérifiez l'existence d'un répertoire pour chaque équipe (en ignorant application2 pour le moment) :

    • admin/
    • réseau /
    • shared/
    • application1/
  2. Créez le fichier terraform.tfvars :

    cp terraform.tfvars.template terraform.tfvars
    

    Ensuite, éditez terraform.tfvars pour définir ces variables:

    • ssh_key_name- il est nécessaire de spécifier une clé SSH existante dans la ibm_region, comme indiqué dans la section Avant de commencer ci-dessus.
    • ibm_region- remplacez la valeur par défaut, us-south, si nécessaire. La commande CLI ibmcloud regions affiche toutes les régions possibles.
    • basename- remplace la valeur par défaut, widget0, par un nom de 7 caractères ou moins, si nécessaire. La plupart des ressources créées utilisent ce nom avec un préfixe de nom.
    • Ne pas annuler la mise en commentaire de transit_gateway ou shared_lb pour le moment.
  3. Utilisateurs Windows uniquement: Si git ne crée pas le lien symbolique sur votre ordinateur Windows, il est nécessaire de copier le contenu des fichiers dans les dossiers de l'équipe :

    cp variables.tf terraform.tfvars admin
    cp variables.tf terraform.tfvars network
    cp variables.tf terraform.tfvars shared
    cp variables.tf terraform.tfvars application1
    

Remarque sur le fait de devenir membre d'équipe

Il est possible de renseigner le groupe d'accès de chaque équipe avec des utilisateurs. Mais plutôt que de créer des utilisateurs, ce tutoriel va créer un identifiant de service dans le groupe d'accès de chaque équipe. Vous êtes l'administrateur et vous allez devenir un membre des différents groupes d'accès en utilisant la clé d'API pour l'ID de service de l'équipe. Les noms d'ID service sont au format ${basename}-x, où x correspond à network, shared, application1 et application2. Vous renseignerez ultérieurement un fichier local.env dans le répertoire de chaque équipe avec un contenu similaire au suivant :

export TF_VAR_ibmcloud_api_key=0thisIsNotARealKeyALX0vkLNSUFC7rMLEWYpVtyZaS9

A chaque étape, lorsque vous cd dans un répertoire d'équipe, on vous rappellera d'exécuter : source local.env

Terraform va être utilisé pour créer les ressources. Ouvrez admin/main.tf et notez la clause provider ibm et la référence à ibmcloud_api_key initialisée à partir de la variable d'environnement :

provider ibm {
 ibmcloud_api_key = var.ibmcloud_api_key # initialized with the TF_VAR_ibmcloud_api_key
}

Si vous devez utiliser le CLI IBM Cloud En tant que membre de l'équipe :

ibmcloud login --apikey $TF_VAR_ibmcloud_api_key

Création des ressources compatibles IAM (équipe Admin)

L'équipe d'administrateurs va avoir besoin d'un accès aux ressources compatibles IAM dans le compte utilisé dans ce tutoriel. Voir Comment affecter un accès complet à un utilisateur en tant qu'administrateur de compte ?. L'équipe d'administration sera responsable de la création des ressources IAM. Les instructions ci-dessous utilisent la commande ibmcloud iam api-key-create pour créer une clé d'API pour l'administrateur. La clé de l'API sera utilisée par terraform pour effectuer des tâches en votre nom.

Les clés PI sont équivalentes à un mot de passe pour votre compte. Gardez les clés de l'API en sécurité.

  1. Initialisez et vérifiez la variable shell de nom de base. Vérifiez qu'elle correspond au nom de base du fichier terraform.tfvars :

    eval $(grep basename terraform.tfvars | sed -e 's/  *//g' -e 's/#.*//')
    echo basename=$basename
    
  2. Changez de répertoire, générez et sourcez votre clé d'API personnelle dans l'environnement local. Quand Terraform est appelé, il devient vous. Terraform sera l'administrateur :

    cd admin
    echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam api-key-create $basename-admin --output json | jq .apikey) > local.env
    cat local.env
    source local.env
    
  3. L'application du fichier de configuration main.tf Terraform crée les ressources suivantes :

    • Des groupes de ressources pour chaque équipe
    • Des groupes d'accès pour chaque équipe et un ID service dans chaque groupe d'accès
    • Des règles de groupe d'accès pour les groupes de ressources
    • Des règles de groupe d'accès pour les ressources
    terraform init
    terraform apply
    
  4. Vérifiez que les ressources ont été créées:

    ibmcloud resource groups | grep $basename
    
    ibmcloud iam access-groups | grep $basename
    
    ibmcloud iam service-ids | grep $basename
    
    ibmcloud iam access-group-policies $basename-network
    

    La sortie ressemblera à ceci:

    $ ibmcloud resource groups | grep $basename
    widget0-application2   36b06a303f224f28ad42aebbb491cc44   false           ACTIVE
    widget0-shared         91518c45e47a427fa4f63edb58e4f227   false           ACTIVE
    widget0-network        bf6e75cd71854576a31056abced2abf0   false           ACTIVE
    widget0-application1   db2f3dc8aacf4a6aa2d2fa07e795cb57   false           ACTIVE
    $ ibmcloud iam access-groups | grep $basename
    widget0-application1   AccessGroupId-26b7ef37-78db-4a2c-a2af-7f6591e73c15   application1 administrators
    widget0-application2   AccessGroupId-8afdec20-f760-4a15-8f3e-296d81818028   application2 administrators
    widget0-network        AccessGroupId-d50b129d-9adc-4fc4-b297-487b3f938ec5   network administrators
    widget0-shared         AccessGroupId-30d73f44-5602-47a7-846e-e6480c9dceff   shared administrators
    $ ibmcloud iam service-ids | grep $basename
    ServiceId-5e919b97-380c-4343-a337-3901cafbd956   widget0-application2                                                                                                       2020-07-15T21:25+0000   2020-07-15T22:03+0000   application 2 service id                                                                                                                                              false
    ServiceId-307df062-f4b7-45f8-8ec8-94ad1ed61730   widget0-network                                                                                                            2020-07-15T21:49+0000   2020-07-15T22:03+0000   network service id                                                                                                                                                    false
    $ ibmcloud iam access-group-policies $basename-network
    Retrieving all policies of access group widget0-network under account 8675309 as jenny@example.com
    OK
    
    Policy ID:   00ceb354-7360-4ad5-9fda-5c03e462c5c0
    Roles:       Editor
    Resources:
                 Resource Group ID     91518c45e47a427fa4f63edb58e4f227
                 Resource Group Name   widget0-shared
                 Service Name          is
                 flowLogCollectorId    *
                 Memo                  Policy applies to the resource(s) within the resource group
    
    Policy ID:   115ebe9f-eea0-4308-9e7f-bb887d64426b
    Roles:       Editor
    Resources:
                 Resource Group ID     db2f3dc8aacf4a6aa2d2fa07e795cb57
                 Resource Group Name   widget0-application1
                 Service Name          is
                 vpnGatewayId          *
                 Memo                  Policy applies to the resource(s) within the resource group
    ...
    
  5. Optionnellement, naviguez vers le compte Groupes de ressources et recherchez les groupes de ressources.

  6. Si vous le souhaitez, vous pouvez naviguer vers Groupes d'accès pour voir les groupes d'accès, cliquer sur un groupe d'accès, puis cliquer sur le panneau ID de service en haut pour voir l'ID de service créé.

Création de VPC et de DNS (équipe network)

L'équipe network crée les ressources réseau pour correspondre à l'architecture, garantissant ainsi que les objectifs de connectivité sont satisfaits et que les équipes sont isolées dans leurs VPC. Elle ne souhaite pas contrôler les détails des instances VPC. Il est probable que le nombre d'applications, la taille des ordinateurs, les enregistrements DNS pour les microservices, etc. soient en constante évolution et ne préoccupent pas l'équipe réseau.

L'équipe d'administrateurs leur a fourni les droits d'accès appropriés pour créer les ressources is de VPC, le DNS Services et le service Transit Gateway.

  1. Changez de répertoire, générez une clé API dans le local.env et devenez membre du groupe d'accès au réseau :

    team=network
    cd ../$team
    echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam service-api-key-create $team $basename-$team --output json | jq .apikey) > local.env
    cat local.env
    source local.env
    
  2. Si vous le souhaitez, vous pouvez ouvrir le fichier variables_network.tf et noter la spécification du bloc CIDR et la disposition de la zone. Dans l'extrait ci-dessous, remarquez que shared et application1 sont spécifiés sans que les adresses IP ne se chevauchent :

    variable network_architecture {
      default = {
        shared = {
          cidr        = "10.0.0.0/16"
          cidr_remote = "10.0.0.0/8"
          zones = {
            z1 = {
              zone_id = "1",
              cidr    = "10.0.0.0/24",
            }
            z2 = {
              zone_id = "2",
              cidr    = "10.0.1.0/24",
        ...
        application1 = {
          cidr        = "10.1.0.0/16"
          cidr_remote = "0.0.0.0"
          zones = {
            z1 = {
              zone_id = "1",
              cidr    = "10.1.0.0/24",
            }
            z2 = {
              zone_id = "2",
              cidr    = "10.1.1.0/24",
         ...
    

    Transit Gateway aura une connexion à chaque VPC et acheminera le trafic en fonction des plages CIDR. Ainsi, éviter les chevauchements garantira le succès.

  3. Créez les ressources :

    terraform init
    terraform apply
    
  4. Répertoriez les ressources VPC

    Les ressources VPC créées sont récapitulées par la sortie de la commande de sous-réseaux, affichée ci-dessous, modifiée à des fins de concision. Remarquez les trois VPC, les blocs CIDR qui ne se chevauchent pas et l'appartenance aux groupes de ressources :

    ibmcloud target -r $(grep ibm_region terraform.tfvars | sed -e 's/  *//g' -e 's/#.*//' -e 's/.*=//' -e 's/"//g')
    ibmcloud is subnets --all-resource-groups | grep $basename
    

    La sortie ressemble à ceci :

    $ ibmcloud is subnets --all-resource-groups | grep $basename
    widget0-shared-z1           available   10.0.0.0/24    widget0-shared           us-south-1   widget0-shared
    widget0-shared-z2           available   10.0.1.0/24    widget0-shared           us-south-2   widget0-shared
    widget0-shared-z3           available   10.0.2.0/24    widget0-shared           us-south-3   widget0-shared
    widget0-application1-z1     available   10.1.0.0/24    widget0-application1     us-south-1   widget0-application1
    widget0-application1-z2     available   10.1.1.0/24    widget0-application1     us-south-2   widget0-application1
    widget0-application1-z3     available   10.1.2.0/24    widget0-application1     us-south-3   widget0-application1
    widget0-application2-z1     available   10.2.0.0/24    widget0-application2     us-south-1   widget0-application2
    widget0-application2-z2     available   10.2.1.0/24    widget0-application2     us-south-2   widget0-application2
    widget0-application2-z3     available   10.2.2.0/24    widget0-application2     us-south-3   widget0-application2
    
  5. En option, naviguez vers les nuages privés virtuels et trouvez les VPC, les sous-réseaux et toutes les autres ressources créées ci-dessus.

  6. Optionnellement, examinez la configuration Terraform en main.tf pour comprendre l'initialisation DNS Services L'instance et la zone DNS Services ont été créées avec le fragment Terraform :

    resource "ibm_resource_instance" "dns" {
      name              = "${var.basename}-dns"
      resource_group_id = data.ibm_resource_group.shared.id
      location          = "global"
      service           = "dns-svcs"
      plan              = "standard-dns"
    }
    
    resource "ibm_dns_zone" "widgets_example_com" {
      name        = "widgets.example.com"
      instance_id = ibm_resource_instance.dns.guid
      description = "this is a description"
      label       = "this-is-a-label"
    }
    

    La zone est ensuite ajoutée à un VPC en tant que réseau autorisé :

    resource "ibm_dns_permitted_network" "shared" {
      instance_id = ibm_resource_instance.dns.guid
      zone_id     = ibm_dns_zone.widgets_example_com.zone_id
      vpc_crn     = module.vpc_shared.vpc.crn
      type        = "vpc"
    }
    
    
  7. Affichez la configuration DNS. Une instance DNS Services a été créée. La zone widgets.example.com a été créée. Enfin, la zone a été ajoutée à tous les VPC.

    ibmcloud dns instances
    
    ibmcloud dns zones -i $basename-dns
    
    zone_id=$(ibmcloud dns zones -i $basename-dns --output json | jq -r '.[] | .id')
    ibmcloud dns permitted-networks $zone_id -i $basename-dns
    

    Le résultat ressemblera à ceci :

    $ ibmcloud dns instances
    Retrieving service instances for service 'dns-svcs' ...
    OK
    Name          ID                                     Location   State    Service Name   
    widget0-dns   3b0d5546-5999-4c7e-a757-f5fd21dd44ed   global     active   dns-svcs   
    $ ibmcloud dns zones -i $basename-dns
    Listing zones for service instance 'widget0-dns' ...
    OK
    ID                                               Name                  Status   
    5a1a2295-1c38-49dd-9809-aaaf5a127e79c1b          widgets.example.com   ACTIVE   
    $ zone_id=$(ibmcloud dns zones -i $basename-dns --output json | jq -r '.[] | .id')
    $ ibmcloud dns permitted-networks $zone_id -i $basename-dns
    Listing permitted networks for zone '5a1a2295-1c38-49dd-9809-f5a127e79c1b' ...
    OK
    Name                   ID                                          Type   VPC_CRN                                                                                                               State   
    widget0-shared         r006-353208ab-4e95-46fb-934b-b5566cde8975   vpc    crn:v1:bluemix:public:is:us-south:a/713c783d9a507a53135fe6793c37cc74::vpc:r006-353208ab-4e95-46fb-934b-b5566cde8975   ACTIVE   
    widget0-application1   r006-287258c6-2eb3-4908-b326-6f03c3e47aa6   vpc    crn:v1:bluemix:public:is:us-south:a/713c783d9a507a53135fe6793c37cc74::vpc:r006-287258c6-2eb3-4908-b326-6f03c3e47aa6   ACTIVE   
    widget0-application2   r006-fa51e99e-bd93-4451-a4eb-76eed9939d3c   vpc    crn:v1:bluemix:public:is:us-south:a/713c783d9a507a53135fe6793c37cc74::vpc:r006-fa51e99e-bd93-4451-a4eb-76eed9939d3c   ACTIVE   
    
  8. Optionnellement, naviguez dans la liste des ressources et trouvez le DNS Services, cliquez dessus et étudiez-le.

Créer le microservice partagé et l'enregistrement DNS associé (Shared Team)

  1. Changez de répertoire, générez une clé API dans le local.env et devenez membre du groupe d'accès partagé :

    team=shared
    cd ../$team
    echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam service-api-key-create $team $basename-$team --output json | jq .apikey) > local.env
    cat local.env
    source local.env
    
  2. Si vous le souhaitez, vous pouvez à ce stade approfondir le code source de Terraform. L'équipe commune va fournir des microservices. Bien que l'équipe network ait déjà créé le VPC partagé et certaines ressources réseau, l'équipe shared crée l'instance et choisit le profil d'instance. Un script de configuration Linux et une application de démonstration simple sont fournis dans l'attribut user_data et discutés à la section Equipe Application ci-dessous.

    Dans main.tf notez les deux ressources suivantes :

    locals {
      network_context = data.terraform_remote_state.network.outputs.shared
    }
    
    resource ibm_is_instance "vsishared" {
      name           = "${var.basename}-shared-vsi"
      vpc            = local.network_context.vpc.id
      resource_group = data.ibm_resource_group.shared.id
      zone           = local.network_context.subnets["z1"].zone
      keys           = [data.ibm_is_ssh_key.ssh_key.id]
      image          = data.ibm_is_image.image.id
      profile        = var.profile[var.generation]
    
      primary_network_interface {
        subnet = local.network_context.subnets["z1"].id
        security_groups = [
          local.network_context.security_group_outbound_all.id, # nodejs is not available on an IBM mirror
          local.network_context.security_group_ibm_dns.id,
          local.network_context.security_group_data_inbound.id,
        ]
      }
      user_data = module.user_data_app.user_data_centos
    }
    
    resource ibm_dns_resource_record "shared" {
      count = var.shared_lb ? 0 : 1 # shared load balancer?
      instance_id = local.network_context.dns.guid
      zone_id     = local.network_context.dns.zone_id
      type        = "A"
      name        = "shared"
      rdata       = ibm_is_instance.vsishared.primary_network_interface[0].primary_ip.address
      ttl         = 3600
    }
    

    Le contexte local.network_context ci-dessus correspond à la sortie générée par l'équipe network spécifiquement pour l'équipe shared.

  3. Créez les ressources partagées :

    terraform init
    terraform apply
    
  4. Optionnellement, naviguez vers les instances de serveurs virtuels pour le VPC et trouvez l'instance partagée. Cliquez dessus et vérifiez les points suivants :

    • L'instance n'a pas de connectivité entrante depuis Internet (vérifiez les groupes de sécurité)
    • Localisez l'adresse IP privée
  5. Optionnellement, naviguez dans la liste des ressources et trouvez le DNS Services, cliquez dessus et trouvez l'enregistrement DNS avec le nom partagé. Notez que la valeur correspond à l'adresse IP privée de l'instance.

Créer un microservice public pour une applicationApplication1 Team)

  1. Changez de répertoire, générez une clé d'API dans local.env et devenez membre du groupe d'accès application1 :

    team=application1
    cd ../$team
    echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam service-api-key-create $team $basename-$team --output json | jq .apikey) > local.env
    cat local.env
    source local.env
    

    Les ressources de l'équipe application1 sont très similaires à celle de l'équipe shared. En fait, elles sont un peu plus simples, car il n'est pas nécessaire de placer des enregistrements dans le DNS Services L'application utilise l'adresse http://shared.widgets.example.com pour accéder au microservice partagé.

  2. Optionnellement, étudier le code source qui initialise l'instance CentOS. Il a été capturé dans un module Terraform partagé par toutes les équipes au cours de cette phase exploratoire.

    ../common/user_data_app/main.tf:

    locals {
      shared_app_user_data_centos = <<EOS
    #!/bin/sh
    curl -sL https://rpm.nodesource.com/setup_20.x | sudo bash -
    yum install nodejs -y
    cat > /app.js << 'EOF'
    ${file("${path.module}/app.js")}
    EOF
    cat > /lib/systemd/system/a-app.service << 'EOF'
    ${file("${path.module}/a-app.service")}
    EOF
    systemctl daemon-reload
    systemctl start a-app
    EOS
    }
    
    output user_data_centos {
      value = replace(local.shared_app_user_data_centos, "REMOTE_IP", var.remote_ip)
    }
    

    Explications détaillées :

    • Nodejs est installé avec les commandes curl et yum
    • L'application nodejs est placée dans /app.js.
    • Un service systemctl est créé pour app.js
    • Le service est démarré.
  3. Vous pouvez étudier le contenu d'app.js. Il comporte deux sections particulièrement intéressantes. Tout d'abord, le lien /info renvoie une description de l'instance qui exécute l'application. ../common/user_data_app/app.js:

    const server = http.createServer((req, res) => {
      switch(req.url) {
      case '/info':
        res.statusCode = 200;
        res.setHeader('Content-Type', 'application/json');
        res.end(JSON.stringify({
          req_url:  req.url,
          os_hostname:  os.hostname(),
          ipArrays: ips()
        }, null, 3));
        break
      case '/remote':
        getRemote(req, res)
        break
    

    Deuxièmement, le lien /remote appelle un serveur distant IP et renvoie la description de ce serveur distant ainsi que les adresses remote_url et remote_ip utilisées pour accéder au serveur distant.

    const IP='REMOTE_IP'
    
    function getRemote(req, res) {
      path = '/info'
      remote_url = 'http://' + IP + ':3000' + path
      http.get(remote_url, (resp) => {
        let rawData = '';
        resp.on('data', (chunk) => { rawData += chunk; });
        resp.on('end', () => {
          try {
            console.log(rawData)
            rawObj = JSON.parse(rawData)
            res.statusCode = 200;
            res.end(JSON.stringify({remote_url: remote_url, remote_ip: resp.connection.remoteAddress, remote_info: rawObj}, null, 3))
    

    Dans notre cas, le REMOTE_IP sera shared.widgets.example.com en raison de ce qui suit dans common/user_data_app/main.tf:

    output user_data_centos {
      value = replace(local.shared_app_user_data_centos, "REMOTE_IP", var.remote_ip)
    }
    

    De retour dans application1/main.tf :

    module user_data_app {
      source    = "../common/user_data_app"
      remote_ip = "shared.widgets.example.com"
    }
    
  4. Créez les ressources :

    terraform init
    terraform apply
    

    Les résultats devraient ressembler à ceci :

    $ terraform apply
    ...
    Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
    
    Outputs:
    
    ibm1_private_ip = "10.1.0.4"
    ibm1_public_ip = "52.116.140.202"
    test_info = "curl 52.116.140.202:3000/info"
    test_remote = "curl 52.116.140.202:3000/remote"
    

    Essayez les deux commandes curl (test_info, test_remote) qui ont été suggérées ci-dessus. Copiez les instructions de votre sortie.

    curl 52.116.140.202:3000/info
    

    La première se traduit par quelque chose comme ce qui a été capturé ci-dessous:

    {
       "req_url": "/info",
       "os_hostname": "widget0-application1-vsi",
       "ipArrays": [
          [
             "10.1.0.4"
          ]
       ]
    }
    

    Ensuite, essayez la deuxième commande (à partir de votre sortie):

    curl 52.116.140.202:3000/remote
    

    Attendez que la deuxième commande de curl n'aboutisse pas. Corrigez-la à l'étape suivante. Souvenez-vous de ces commandes curl, vous les utiliserez à nouveau sous peu.

Créer Transit Gateway

IBM Cloud Transit Gateway est un service réseau utilisé pour interconnecter IBM Cloud Les ressources VPC offrent une évolutivité dynamique, une haute disponibilité et la tranquillité d'esprit que les données ne traversent pas l'internet public. Auparavant, les blocs CIDR pour chacun des VPC ont été choisis sans chevauchement pour permettre à Transit Gateway d'acheminer les paquets en fonction de l'adresse IP.

  1. Changez de répertoire et devenez membre du groupe réseau (utilisez la clé d'API existante) :

    cd ../network
    source local.env
    
  2. Vous avez la possibilité d'étudier les fichiers Terraform. Ouvrez le fichier main.tf et vous verrez les ressources Transit Gateway (ibm_tg). Chacun a un count = var.transit_gateway ? 1 : 0. Il s'agit d'une construction Terraform qui crée un tableau de ressources de longueur 1 ou 0 en fonction de la valeur de transit_gateway. Un tableau de longueur 0 se traduira par "aucune ressource". Exemple :

    resource "ibm_tg_gateway" "tgw"{
      count = var.transit_gateway ? 1 : 0
      name              = "${var.basename}-tgw"
      location          = var.ibm_region
      global            = false
      resource_group    = data.ibm_resource_group.network.id
    }
    
  3. Modifiez le terraform.tfvars fichier et décommentez la ligne transit_gateway = true pour permettre le provisionnement de Transit Gateway

  4. Appliquez la modification

    terraform apply
    
  5. Imprimez Transit Gateway à l'aide des commandes ci-dessous.

    ibmcloud tg gateways
    GATEWAY_ID=$(ibmcloud tg gateways --output json | sed -e '/^OK$/d' | jq -r '.[]|select(.name=="'$basename-tgw'")|.id')
    ibmcloud tg connections $GATEWAY_ID
    

    Notez les trois connexions VPC dans la sortie. Elles devraient ressembler à ceci :

    $ ibmcloud tg gateways
    Listing gateways under account
    OK
    
    GatewayID           e2801c16-1a6d-4d47-9c58-1a3b3c1d9b1b
    CRN                 crn:v1:bluemix:public:transit:us-south:a/86785309::gateway:e2801c16-1a6d-4d47-9c58-1a3b3c1d9b1b
    Name                widget0-tgw
    Routing             local
    Location            us-south
    Created             2020-07-16T09:09:38.048-07:00
    Resource group ID   bf6e75cd71854576a31056abced2abf0
    Status              available
    
    $ GATEWAY_ID=$(ibmcloud tg gateways --output json | sed -e '/^OK$/d' | jq -r '.[]|select(.name=="'$basename-tgw'")|.id')
    $ ibmcloud tg connections $GATEWAY_ID
    Listing connections for gateway e2801c16-1a6d-4d47-9c58-1a3b3c1d9b1b under account
    OK
    
    Name                    widget0-shared
    Network Type            vpc
    Connection ID           dff6ecfd-388d-471a-908a-98880426fbee
    Status                  attached
    Default Prefix Filter   permit
    NetworkID               crn:v1:bluemix:public:is:us-south:a/86785309::vpc:r006-b08a7c2c-c0ea-4908-b0ab-b96cd8ba221a
    
    Name                    widget0-application1
    Network Type            vpc
    Connection ID           bbce29f9-9ce4-47d4-911d-5341601cea07
    Status                  attached
    Default Prefix Filter   permit
    NetworkID               crn:v1:bluemix:public:is:us-south:a/86785309::vpc:r006-8fdc0e7e-3a98-4f6b-93e0-505c61e3faac
    
    Name                    widget0-application2
    Network Type            vpc
    Connection ID           208c00cc-aee2-498e-8b1c-37ddc276f200
    Status                  attached
    Default Prefix Filter   permit
    NetworkID               crn:v1:bluemix:public:is:us-south:a/86785309::vpc:r006-fa80afa7-b16b-4db7-95dd-69a558db4285
    
  6. Il est possible de naviguer dans Transit Gateway et de trouver la passerelle créée ci-dessus.

  7. Exécutez la commande curl ci-dessus qui a échoué pour vérifier qu'il existe un chemin d'accès entre le VPC application1 et le VPC partagé. Il devrait être similaire à ceci :

    $ curl 169.48.152.220:3000/remote
    
    {
       "remote_url": "http://shared.widgets.example.com:3000/info",
       "remote_ip": "10.0.0.4",
       "remote_info": {
          "req_url": "/info",
          "os_hostname": "widget0-shared-vsi",
          "ipArrays": [
             [
                "10.0.0.4"
             ]
          ]
       }
    }
    

Insertion d'un Load Balancer et remplacement de l'enregistrement DNS

Ajout d'un équilibreur de charge à l'architecture
Ajout d'un équilibreur de charge à l'architecture

  1. Changez de répertoire et devenez membre du groupe d'accès partagé (utilisez la clé d'API existante) :

    cd ../shared
    source local.env
    
  2. Vous avez la possibilité d'étudier les fichiers de configuration Terraform. Le service Load Balancer for VPC distribue le trafic entre plusieurs instances de serveur de la même région de votre PC. L'équipe shared peut équilibrer la charge entre plusieurs instances. Pour le moment, le pool d'équilibrage de charge comporte la seule instance créée précédemment. Voir le lb.tf pour la mise en œuvre. Dans la ressource ibm_is_lb, utilisez la clause dns pour identifier la zone DNS privée afin de placer l'adresse DNS de l'équilibreur de charge:

    resource "ibm_is_lb" "shared_lb" {
      ...
      dns {
        instance_crn = local.network_context.dns.crn
        zone_id      = local.network_context.dns.zone_id
      }
    }
    
  3. Fournissez un enregistrement DNS CNAME shared.widgets.example.com pour identifier l'équilibreur de charge, afin que les applications continuent de fonctionner sans modifications du code source:

    # shared.widgets.example.com
    resource ibm_dns_resource_record "shared_lb" {
      count = var.shared_lb ? 1 : 0 # shared load balancer?
      instance_id = local.network_context.dns.guid
      zone_id     = local.network_context.dns.zone_id
      type        = "CNAME"
      name        = "shared"
      rdata       = ibm_is_lb.shared_lb[0].hostname
      ttl         = 3600
    }
    

    Le même count = var.shared_lb ? 1 : 0 est utilisé. Le nom d'hôte de l'équilibreur de charge est similaire à b7911a41-us-south.widgets.example.com. L'enregistrement CNAME sera utilisé par les applications.

  4. Modifiez le fichier terraform.tfvars et décompressez shared_lb = true. Appliquez ensuite les modifications:

    terraform apply
    
  5. Exécutez la commande curl .../remote de la section application1 précédente (ignorez la sortie qui vient d'être générée pour le microservice partagé). Remarquez que remote_ip est 10.0.1.4, l'équilibreur de charge, et que remote_info est 10.0.0.4, l'instance. Curl quelques fois de plus et remarquez que le remote_ip de l'équilibreur de charge peut changer.

    $ curl 169.48.152.220:3000/remote
    
    {
       "remote_url": "http://shared.widgets.example.com:3000/info",
       "remote_ip": "10.0.1.4",
       "remote_info": {
          "req_url": "/info",
          "os_hostname": "widget0-shared-vsi",
          "ipArrays": [
             [
                "10.0.0.4"
             ]
          ]
       }
    }
    

Créer un microservice public pour une applicationApplication2 Team)

L'environnement de la deuxième équipe application est identique à celui de la première. Il est possible de créer l'application2 en modifiant l'application1

  1. Entrez le répertoire ./application1 et créez le répertoire application2

    cd ../application1
    mkdir ../application2
    sed -e 's/application1/application2/g' main.tf > ../application2/main.tf
    cp terraform.tfvars variables.tf versions.tf ../application2
    
  2. Changez de répertoire, générez une clé API dans le local.env, et devenez membre du groupe d'accès application2:

    team=application2
    cd ../$team
    echo export TF_VAR_ibmcloud_api_key=$(ibmcloud iam service-api-key-create $team $basename-$team --output json | jq .apikey) > local.env
    cat local.env
    source local.env
    
  3. Créez les ressources :

    terraform init
    terraform apply
    
  4. Testez les commandes curl

Suppression de ressources

  1. Détruisez les ressources. Vous pouvez changer cd) les répertoires de l'équipe dans l'ordre, et exécuter source local.env; terraform destroy. L'ordre est application2, application1, shared (partagé), network (réseau), admin. Il existe également un script qui peut le faire pour vous :

    cd ..
    ./bin/destroy.sh
    

Extension du tutoriel

Autres considérations

  • L'équipe Application fournit un accès à l'application via une adresse IP flottante. Pensez à la connecter à IBM Cloud Internet Services. Ces services peuvent gérer le DNS public et garantir la sécurité. La rubrique Déploiement de charges de travail isolées sur plusieurs emplacements et zones contient un exemple.
  • L'équipe d'application peut évoluer horizontalement à l'aide d'un équilibreur de charge, comme l'équipe partagée.
  • L'équipe partagée peut ajouter des instances supplémentaires à l'équilibreur de charge en ajoutant des instances à l'shared/main.tf
  • L'équipe partagée pourrait changer sa plateforme de mise en œuvre pour Kubernetes.

Continuous Delivery

  • L'installation du logiciel est actuellement effectuée lors de la création de l'instance VPC. La distribution de nouvelles versions de logiciels à la production n'a pas été envisagée.
  • Pour les microservices partagés, un nouveau VSI pourrait être créé avec une nouvelle version et, après vérification, le DNS pourrait être ajusté ou l'équilibreur de charge partagé pourrait être utilisé pour passer à la nouvelle version.

Automatisation, préproduction et développement

  • Pour la production, les équipes peuvent avoir chacune leur propre espace de travail Schematics Avec Schematics, des configurations Terraform peuvent être exécutées directement dans le cloud où l'état et la sortie peuvent être partagés.
  • Les scripts Terraform peuvent être ajustés pour permettre des environnements de préproduction et de développement. Placez ces environnements dans de nouveaux comptes.
  • Un environnement de déploiement continu peut être construit pour déplacer le code et les environnements via le développement, la préproduction, jusqu'à la production. Une récupération en amont est nécessaire ? Comment procéder ?

Conclusions

L'architecture d'un système est influencée par le confinement et la propriété des ressources de cloud. Il est important pour les architectes de tous les aspects du système de faire part de leurs préoccupations concernant l'architecture. Chaque équipe a besoin de pouvoir contrôler les ressources qu'elle produit et publie. L'isolement permet de réduire la probabilité des problèmes et de limiter l'impacte en cas de problème.