Privacy basata sul team utilizzando IAM, VPC, Transit Gateway e DNS

Questa esercitazione può comportare degli addebiti. Utilizzate l'Estimatore di costi per generare una stima dei costi in base all'utilizzo previsto.

I microservizi sono popolari perché consentono a un'azienda di organizzare i propri team di sviluppo intorno ai servizi che forniscono. Questo tutorial illustra le fasi di creazione dell'infrastruttura per un IBM Cloud® Virtual Private Cloud (VPC) basata su un'architettura di microservizi. In questa architettura, i VPC sono collegati tra loro utilizzando IBM Cloud® Transit Gateway. Si accede a un insieme di microservizi condivisi tramite nomi di host registrati nel IBM Cloud® DNS Services. Ogni VPC viene gestito da un team separato isolato da IBM Cloud® Identity and Access Management. Opzionalmente, si può usare un IBM Cloud® Load Balancer per scalare il microservizio condiviso.

Obiettivi

  • Scopri come isolare l'infrastruttura utilizzando IAM e i gruppi di risorse
  • Crea i VPC e le risorse associate come le sottoreti, gli ACL di rete, i gruppi di sicurezza e le istanze.
  • Indirizzare i microservizi tramite la risoluzione dei nomi DNS utilizzando DNS Services.
  • Connetti i VPC tramite Transit Gateway.
  • Configura in modo trasparente un Load Balancer per un'applicazione.

Architettura astratta:

dell'architettura del

Nel diagramma precedente l'utente finale accede alle applicazioni. Le applicazioni sfruttano microservizi condivisi. L'azienda dispone di team DevOps separati che gestiscono application1, application2 e shared. Un team di rete si focalizza sulla connettività e sulla sicurezza di rete. I team DevOps gestiscono le Virtual Service Instances, VSI, utilizzate per implementare i servizi che creano e supportano.

Architettura concreta

La seguente architettura implementa i requisiti di isolamento e connettività impostati dall'azienda. Nota che application1, shared e application2 sono VPC. La singola zona e la sottorete in ogni VPC possono essere espanse in un'implementazione multizona più dettagliata nel tempo.

Architettura dell'esercitazione
Architettura dell'esercitazione

Prima di iniziare

Questa esercitazione richiede:

  • IBM Cloud con questi plugin:
    • Transit Gateway (tg)
    • IBM Cloud VPC (vpc-infrastructure)
    • DNS Services (dns)
  • git per clonare il repository di codice sorgente.
  • CLI terraform per eseguire i comandi Terraform.

Le istruzioni per scaricare e installare questi strumenti per il vostro ambiente operativo sono contenute nella guida Getting started with solution tutorials.

Inoltre:

  • Controlla le autorizzazioni utente. Assicurati che il tuo account utente disponga di autorizzazioni sufficienti per creare e gestire le risorse VPC, creare un IBM Cloud® Transit Gateway e creare i servizi IBM Cloud® Transit Gateway. Vedi l'elenco delle autorizzazioni richieste per VPC. Avrai anche bisogno della capacità di creare gruppi di risorse e risorse IAM come gruppi di accesso, politiche, ID servizio, ...
  • Hai bisogno di una chiave SSH per collegarti ai server virtuali. Se non si dispone di una chiave SSH, consultare le istruzioni per la creazione di una chiave per VPC.

Pianifica l'ambiente Identity and Access Management

Il team di gestione abiliterà gli altri team a gestire le loro risorse per quanto possibile. Il team di gestione gestirà gli utenti e controllerà l'accesso ma non creerà o eliminerà le risorse mostrate nel diagramma dell'architettura.

Editor, Operatore, Visualizzatore e Gestore sono ruoli di accesso IAM. Ogni servizio definisce il significato esatto dei ruoli e delle azioni associate.

Team:

  • Gestione - definisce la struttura dell'account ad esempio i gruppi di risorse, i gruppi di accesso, gli utenti e i ruoli.
  • Rete - crea risorse di rete come il servizio DNS Services, il servizio Transit Gateway, il VPC e le sottoreti.
  • Condiviso - crea la VSI e i dispositivi a blocchi nel VPC condiviso. Crea i record DNS per i servizi condivisi.
  • Application1 - crea la VSI e i dispositivi a blocchi nel VPC application1
  • Application2 - crea la VSI e i dispositivi a blocchi nel VPC application2.

Concettuale IAM

Team di rete

È stato implementato un modello di proprietà di team concettuale. Il team network amministra tutte le risorse di rete e quindi la maggior parte di quanto mostrato nel diagramma.

Architettura incentrata sul team di rete
Architettura incentrata sul team di rete

Team condiviso

Il team condiviso crea la VSI nel suo VPC isolato. Inoltre, il team deve scrivere i record nel servizio DNS, poiché gli indirizzi IP dei VSI sono determinati al momento della creazione. L'accesso da operatore al VPC, alle sottoreti e ai gruppi di sicurezza è necessario per creare una VSI.

Architettura incentrata sul team condiviso
Architettura incentrata sul team condiviso

I team di applicazione hanno bisogno dello stesso accesso del team condiviso tranne che dell'accesso gestore a DNS Services.

Accesso al team dell'applicazione:

Architettura incentrata sul team dell'applicazione
Architettura incentrata sul team dell'applicazione

Architettura IAM

Se hai una buona conoscenza dei gruppi di risorse e dei gruppi di accesso IAM, puoi scorrere velocemente questa sezione e iniziare a creare le risorse.

Gruppi di accesso

Sarà creato un gruppo di accesso per ogni team. Vengono aggiunte le politiche di accesso ai gruppi di accesso e poi gli utenti (membri del team) vengono aggiunti al gruppo di accesso per concedere l'accesso.

L'istanza del servizio Transit Gateway è gestita esclusivamente dal team di rete. L'accesso da editor è necessario per la creazione. L'accesso da gestore all'istanza creata consente ai VPC di essere collegati a Transit Gateway.

In questo esempio, verrà creata una singola zona DNS, widgets.example.com, il cui accesso sarà consentito a tutte le VPC. L'istanza del servizio DNS viene creata dal team di rete (ruolo editor) consentendo alle zone che lo richiedono il ruolo di gestore. La risoluzione DNS al runtime in un'istanza su un VPC non richiede accesso IAM. Il team condiviso deve elencare le istanze DNS (ruolo Viewer) e aggiungere un record A o CNAME (ruolo Manager).

VPC Infrastructure Service (IS) è formato da circa 15 tipi di servizio diversi. Alcuni riguardano solo il team di rete, come le ACL (liste di controllo degli accessi). Altri interessano solo i team dei microservizi, come le istanze VSI. Ma alcuni sono curati dal team di rete e gestiti dal team dei microservizi, come le sottoreti. Il team di rete creerà la sottorete e un team di microservizi creerà un'istanza in una sottorete. Ai fini di questa esercitazione i tipi di servizio VPC IS, Transit Gateway e DNS vengono riepilogati per ogni gruppo di accesso nella seguente tabella. I contenuti della tabella sono i ruoli richiesti.

Ruoli richiesti assegnati ai team in base alla responsabilità
service rete condiviso applicazione
Transit Gateway Editor, Gestore
DNS Editor, Gestore Visualizzatore, Gestore
IS: ACL di rete Editor
IS: Istanza, Volume, IP mobile, Chiave SSH, Immagine, Load Balancer Editor Editor
IS: VPC, Sottorete, Gruppo di sicurezza Editor Operatore Operatore

Gruppi di risorse

Il team condiviso e il team di rete sono ora ben separati. Ma come viene isolato Application1 da Shared e Application2? Sono editor per gli stessi tipi di servizi.

Qui è dove i gruppi di risorse possono essere utili. Ogni istanza di servizio (cioè risorsa) ha un attributo di gruppo di risorse che viene inizializzato al momento della creazione e non può essere modificato. In altre parole, ogni risorsa si trova in un gruppo di risorse.

Diagramma gruppo di risorse:

Diagramma Gruppo di risorse
Diagramma Gruppo di risorse

A ciascun team di microservizi sarà consentito l'accesso nel corrispondente gruppo di risorse. Il team di rete avrà accesso a tutti questi gruppi di risorse.

Il gruppo di risorse di rete contiene Transit Gateway e il servizio DNS. Il team della rete ha accesso a queste risorse. Il team condiviso avrà accesso Gestore al servizio DNS. Il team condiviso deve scrivere le voci DNS per i servizi condivisi.

Più avanti nell'esercitazione, dopo che tutte le risorse sono state create, può essere informativo aprire l'elenco delle risorse nella console IBM Cloud. È possibile filtrare in base al gruppo di risorse.

Crea un ambiente di lavoro locale

Tutte le operazioni verranno eseguite in una bash shell e facendo uso dei comandi terraform e ibmcloud. Le istruzioni per scaricare e installare questi strumenti per il vostro ambiente operativo sono contenute nella guida Getting started with solution tutorials.

  1. Git clona il seguente repository:

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

    Verifica sia presente una directory per ogni team (tralasciando application2 per ora):

    • admin/
    • rete /
    • shared/
    • application1/
  2. Creare il file terraform.tfvars:

    cp terraform.tfvars.template terraform.tfvars
    

    Successivamente, modificare terraform.tfvars per impostare queste variabili:

    • ssh_key_name- è necessario specificare una chiave SSH esistente nella regione ibm_ come specificato nella sezione Prima di iniziare.
    • ibm_region- sostituisce il valore predefinito, us-south, se necessario. Il comando cli ibmcloud regions visualizzerà tutte le regioni possibili.
    • basename- sostituisce il valore predefinito, widget0, con un nome di 7 caratteri o meno, se necessario. La maggior parte delle risorse create lo utilizzerà come un prefisso del nome.
    • Non eliminare il commento da transit_gateway o shared_lb in questo momento.
  3. Solo per gli utenti Windows: se git non crea il collegamento simbolico sul computer Windows, è necessario copiare il contenuto dei file nelle cartelle del team:

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

Una nota su come diventare un membro del team

È possibile popolare il gruppo di accesso di ogni team con degli utenti. Ma invece di creare utenti, questa esercitazione creerà un ID servizio in ogni gruppo di accesso del team. L'amministratore diventerà un membro dei diversi gruppi di accesso utilizzando la chiave API per l'ID servizio per il team. I nomi degli ID dei servizi sono ${basename}-x dove x è rete, condiviso, application1 e application2. Successivamente popolerai un file local.env nella directory di ogni team con dei contenuti simili ai seguenti:

export TF_VAR_ibmcloud_api_key=0thisIsNotARealKeyALX0vkLNSUFC7rMLEWYpVtyZaS9

In ogni fase, quando cd in una directory di squadra, vi verrà ricordato di eseguire: source local.env

Terraform sarà utilizzato per creare le risorse. Apri admin/main.tf e nota la clausola provider ibm e il riferimento alla ibmcloud_api_key inizializzata dalla variabile di ambiente:

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

Se devi utilizzare la CLI IBM Cloud come membro del team:

ibmcloud login --apikey $TF_VAR_ibmcloud_api_key

Crea le risorse abilitate IAM (team di gestione)

Il team di gestione avrà bisogno dell'accesso da amministratore alle risorse abilitate IAM nell'account utilizzato in questa esercitazione. Vedi Come assegno a un utente l'accesso completo come amministratore dell'account?. Il team di amministrazione sarà responsabile della creazione delle risorse IAM. Le seguenti istruzioni utilizzano il comando ibmcloud iam api-key-create per creare una chiave API per l'amministratore. La chiave API verrà utilizzata da Terraform per eseguire le attività per tuo conto.

Le chiavi PI sono le stesse di una password per l'account. Tenere al sicuro le chiavi API.

  1. Inizializza e verifica la variabile shell basename. Verifica se corrisponde alla basename nel file terraform.tfvars:

    eval $(grep basename terraform.tfvars | sed -e 's/  *//g' -e 's/#.*//')
    echo basename=$basename
    
  2. Modifica la directory e genera la tua chiave API personale in local.env. Quando viene richiamato terraform prenderà il tuo posto. Terraform sarà l'amministratore:

    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'applicazione del file di configurazione di main.tf Terraform crea le seguenti risorse:

    • I gruppi di risorse per ogni team
    • I gruppi di accesso per ogni team e un ID servizio in ogni gruppo di accesso
    • Le politiche del gruppo di accesso per i gruppi di risorse
    • Le politiche del gruppo di accesso per le risorse
    terraform init
    terraform apply
    
  4. Verificare che le risorse siano state create:

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

    L'output sarà simile a questo:

    $ 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. Opzionalmente, navigare nell'account Gruppi di risorse e trovare i gruppi di risorse.

  6. Per visualizzare i gruppi di accesso, fare clic su un gruppo di accesso, quindi fare clic sul pannello ID servizio in alto per visualizzare l'ID servizio creato.

Crea VPC e DNS (team di rete)

Il team di rete creerà le risorse di rete in modo da corrispondere all'architettura in modo da garantire che siano soddisfatti gli obiettivi di connettività e i team siano isolati nei loro VPC. Non desiderano controllare i dettagli delle istanze VPC. È probabile che il numero di applicazioni, le dimensioni dei computer, i record DNS per i microservizi e così via siano in costante evoluzione e non siano una preoccupazione del team di rete.

Il team di gestione ha fornito loro appena la giusta quantità di autorizzazioni per creare le risorse VPC is, DNS Services e il servizio Transit Gateway.

  1. Cambiare directory, generare una chiave API in local.env e diventare membro del gruppo di accesso alla rete:

    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. Facoltativamente, aprire il file variables_network.tf e notare le specifiche del blocco CIDR e il layout della zona. Nello snippet sottostante si noti che shared e application1 sono specificati senza sovrapposizione di indirizzi IP:

    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",
         ...
    

    Il Transit Gateway avrà una connessione a ogni VPC e instrada il traffico basato sugli intervalli CIDR. Quindi, evitare sovrapposizioni garantirà il successo.

  3. Crea le risorse:

    terraform init
    terraform apply
    
  4. Elenca le risorse VPC

    Le risorse VPC create vengono riepilogate dall'output del comando subnets, mostrato qui di seguito e abbreviato. Si notino le tre VPC, i blocchi CIDR non sovrapposti e l'appartenenza ai gruppi di risorse:

    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
    

    L'output sarà simile al seguente:

    $ 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. Facoltativamente, navigare nelle Virtual Private Cloud e trovare le VPC, le sottoreti e tutte le altre risorse create in precedenza.

  6. Facoltativamente, indagare la configurazione di Terraform in main.tf per capire l'inizializzazione di DNS Services. La zona e l'istanza DNS Services sono state create con il frammento 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 zona viene poi aggiunta a un VPC come una rete consentita:

    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. Elenca la configurazione DNS. È stata creata un'istanza DNS Services. È stata creata la zona widgets.example.com. Infine, la zona è stata aggiunta a tutte le 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
    

    Il risultato sarà simile a questo:

    $ 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. In alternativa, navigare nell'elenco delle risorse e trovare il DNS Services, fare clic su di esso e indagare.

Creare il microservizio condiviso e il record DNS associato (Shared Team)

  1. Cambiare directory, generare una chiave API in local.env e diventare membro del gruppo di accesso condiviso:

    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. A questo punto è possibile approfondire il codice sorgente di Terraform. Il team condiviso fornirà microservizi. Sebbene il team di rete abbia già creato il VPC condiviso ed alcune risorse di rete, il team condiviso creerà l'istanza e sceglierà il profilo dell'istanza. Uno script di configurazione Linux e un'applicazione demo semplice vengono forniti nell'attributo user_data e ne discuteremo nella seguente sezione Team dell'applicazione.

    In main.tf nota queste due risorse:

    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
    }
    

    Il precedente local.network_context è l'output generato dal team di rete appositamente per il team condiviso.

  3. Crea le risorse condivise:

    terraform init
    terraform apply
    
  4. Facoltativamente, navigare in Istanze server virtuali per VPC e trovare l'istanza condivisa. Fai clic su di essa e verifica quanto segue:

    • L'istanza non ha la connettività in entrata da internet pubblico (controlla i gruppi di sicurezza)
    • Individua l'indirizzo IP privato
  5. Facoltativamente, navigare nell'elenco delle risorse e trovare il DNS Services, fare clic su di esso e trovare il record DNS con il nome condiviso. Nota che il valore è l'indirizzo IP privato dell'istanza.

Creare un microservizio rivolto al pubblico per un'applicazioneApplication1 Team)

  1. Modifica la directory, genera una chiave API in local.env e diventa un membro del gruppo di accesso 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
    

    Le risorse del team application1 sono molto simili a quelle del team condiviso. In realtà, sono un po' più semplici, poiché non è necessario inserire i record nel DNS Services. L'applicazione utilizza l'indirizzo http://shared.widgets.example.com per accedere al microservizio condiviso.

  2. Opzionalmente, indagare sul codice sorgente che inizializza l'istanza CentOS. È stato catturato in un modulo Terraform condiviso da tutti i team durante questa fase esplorativa.

    ../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)
    }
    

    Spiegazione dettagliata:

    • Nodejs è installato con i comandi curl e yum
    • L'applicazione nodejs viene inserita in /app.js.
    • Viene creato un servizio systemctl per app.js
    • Il servizio è avviato.
  3. Facoltativamente esamina i contenuti di app.js. Ha due sezioni particolarmente interessanti. Innanzitutto, c'è un collegamento /info che restituisce una descrizione dell'istanza che esegue l'applicazione. ../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
    

    In secondo luogo, il collegamento /remote richiama l'IP di un server remoto e restituisce la descrizione del server remoto insieme agli indirizzi remote_url e remote_ip utilizzati per accedervi.

    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))
    

    Nel nostro caso il REMOTE_IP sarà shared.widgets.example.com a causa di quanto segue in common/user_data_app/main.tf::

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

    E torna in application1/main.tf:

    module user_data_app {
      source    = "../common/user_data_app"
      remote_ip = "shared.widgets.example.com"
    }
    
  4. Crea le risorse:

    terraform init
    terraform apply
    

    I risultati sono qualcosa di simile a quanto segue:

    $ 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"
    

    Prova i due comandi curl (test_info, test_remote) suggeriti in precedenza. Copiare le istruzioni dall'output.

    curl 52.116.140.202:3000/info
    

    Il primo si traduce in qualcosa di simile a quello che è stato catturato di seguito:

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

    Quindi, provare il secondo comando (dall'output):

    curl 52.116.140.202:3000/remote
    

    Attendi, quel secondo comando curl non ha funzionato. Correggerlo nel passo successivo. Ricordate questi comandi curl, li userete di nuovo a breve.

Crea Transit Gateway

IBM Cloud Transit Gateway è un servizio di rete utilizzato per interconnettere IBM Cloud le risorse VPC, fornendo una scalabilità dinamica e la tranquillità che i dati non attraversino la rete pubblica Risorse VPC, fornendo scalabilità dinamica, alta disponibilità e la tranquillità di sapere che i dati non attraversano la rete Internet pubblica. In precedenza i blocchi CIDR di ciascun VPC sono stati scelti senza sovrapposizione per consentire a Transit Gateway di instradare i pacchetti in base all'indirizzo IP.

  1. Modifica la directory e diventa un membro del gruppo di rete (utilizza la chiave API esistente):

    cd ../network
    source local.env
    
  2. Facoltativamente esamina i file terraform. Apri il file main.tf e noterai le risorse Transit Gateway (ibm_tg). Ognuno ha un count = var.transit_gateway ? 1 : 0. Questo è un costrutto terraform che crea un array di risorse di lunghezza 1 o 0 in base al valore di transit_gateway. Un array di lunghezza 0 significa che non ci sono risorse. Ad esempio:

    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. Modifica il file terraform.tfvars e elimina il commento dalla riga transit_gateway = true per abilitare il provisioning di Transit Gateway.

  4. Applica la modifica

    terraform apply
    
  5. Stampa Transit Gateway utilizzando i seguenti comandi.

    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
    

    Nota le tre connessioni VPC nell'output. Sarà simile a quanto segue:

    $ 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. Navigare facoltativamente nel Transit Gateway e trovare il gateway creato in precedenza.

  7. Eseguire il comando curl di cui sopra, che è fallito in precedenza, per verificare l'esistenza di un percorso dalla VPC application1 alla VPC condivisa. Il risultato è simile a quanto mostrato di seguito:

    $ 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"
             ]
          ]
       }
    }
    

Inserisci un Load Balancer e sostituisci il record DNS

Aggiunta di un programma di bilanciamento del carico all'architettura
Aggiunta di un programma di bilanciamento del carico all'architettura

  1. Modifica la directory e diventa un membro del gruppo di accesso condiviso (utilizza la chiave API esistente):

    cd ../shared
    source local.env
    
  2. Facoltativamente esamina i file di configurazione terraform. Il Load Balancer per il servizio VPC distribuisce il traffico tra più istanze del server all'interno della stessa regione del tuo VPC. Il team condiviso può bilanciare il carico tra più istanze. Per ora il pool del programma di bilanciamento del carico avrà la sola istanza creata in precedenza. Per l'implementazione, vedere il file lb.tf. Nella risorsa ibm_is_lb utilizza la clausola dns per identificare la zona DNS privata per posizionare l'indirizzo DNS del programma di bilanciamento del carico:

    resource "ibm_is_lb" "shared_lb" {
      ...
      dns {
        instance_crn = local.network_context.dns.crn
        zone_id      = local.network_context.dns.zone_id
      }
    }
    
  3. Fornisci un record CNAME DNS shared.widgets.example.com per identificare il programma di bilanciamento del carico, in modo che le applicazioni continuino a lavorare senza modifiche del codice origine:

    # 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
    }
    

    Viene utilizzato lo stesso count = var.shared_lb ? 1 : 0. Il nome host del programma di bilanciamento del carico sarà simile a b7911a41-us-south.widgets.example.com. Il record CNAME verrà usato dalle applicazioni.

  4. Modificare il file terraform.tfvars e decommentare shared_lb = true. Quindi applicare le modifiche:

    terraform apply
    
  5. Eseguire il comando curl .../remote della sezione precedente application1 (ignorare l'output appena generato per il microservizio condiviso). Si noti che remote_ip è 10.0.1.4, il bilanciatore di carico, e remote_info è 10.0.0.4, l'istanza. Eseguire Curl ancora un paio di volte e notare che il remote_ip del bilanciatore di carico può cambiare.

    $ 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"
             ]
          ]
       }
    }
    

Creare un microservizio rivolto al pubblico per un'applicazioneApplication2 Team)

Il secondo ambiente del team dell'applicazione è identico al primo. Opzionalmente, creare l application2 modificando l'application1.

  1. Immetti la directory ./application1 e crea la directory 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. Cambiare directory, generare una chiave API in local.env e diventare membro del gruppo di accesso 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. Crea le risorse:

    terraform init
    terraform apply
    
  4. Verifica i comandi curl

Rimuovi le risorse

  1. Elimina le risorse. È possibile modificare cd) le directory del team in ordine ed eseguire source local.env; terraform destroy. L'ordine è application2, application1, shared, network, admin. C'è anche uno script che lo farà per te:

    cd ..
    ./bin/destroy.sh
    

Espandi l'esercitazione

Altre considerazioni

  • Il team dell'applicazione fornisce l'accesso all'applicazione tramite un indirizzo IP mobile. Considera di collegarlo a IBM Cloud Internet Services. Può gestire il DNS pubblico e fornire sicurezza. Distribuisci i carichi di lavoro isolati tra più ubicazioni e zone ha un esempio.
  • Il team Applicazioni può scalare orizzontalmente utilizzando un bilanciatore di carico come il team condiviso.
  • Il team condiviso può aggiungere altre istanze al bilanciatore di carico aggiungendo istanze al file shared/main.tf.
  • Il team condiviso potrebbe passare la propria piattaforma di implementazione a Kubernetes.

Continuous Delivery

  • L'installazione del software viene al momento eseguita quando viene creata l'istanza VPC. La fornitura di nuove versioni del software alla produzione non è stata presa in considerazione.
  • Per i microservizi condivisi, è possibile creare un nuovo VSI con una nuova versione e, dopo la verifica, regolare il DNS o utilizzare il bilanciatore di carico condiviso per passare alla nuova versione.

Automazione, preparazione e sviluppo

  • Per la produzione, i team possono avere ciascuno il proprio spazio di lavoro Schematics. Con Schematics, le configurazioni terraform possono essere eseguite direttamente nel cloud dove possono essere condivisi stato e output.
  • Gli script Terraform possono essere modificati per consentire ambienti di preparazione e sviluppo. Inserisci questi ambienti in nuovi account.
  • Un ambiente di distribuzione continua può essere creato per spostare il codice e gli ambienti tra lo sviluppo, la preparazione e la produzione. Il rollback è necessario? Come può essere eseguito?

Conclusioni

L'architettura di un sistema è influenzata dal contenimento e dal proprietario delle risorse cloud. È importante che gli architetti, da tutti gli aspetti del sistema, contribuiscano con i loro dubbi all'architettura. Ogni team ha bisogno della capacità di controllare le risorse che producono e rilasciano. L'isolamento ridurrà il rischio di problemi e conterrà il raggio d'azione quando si verificano dei problemi.