IBM Cloud Docs
Privacidade baseada em equipe usando o IAM, a VPC, o Transit Gateway e o DNS

Privacidade baseada em equipe usando o IAM, a VPC, o Transit Gateway e o DNS

Este tutorial pode incorrer em custos. Use o Estimador de custos para gerar uma estimativa do custo baseada em seu uso projetado.

Os microsserviços são populares porque permitem que uma empresa organize suas equipes de desenvolvimento em torno dos serviços que entregam. Este tutorial o orienta nas etapas de criação de infraestrutura para uma arquitetura de microsserviço baseada em IBM Cloud® Virtual Private Cloud (VPC). Nesta arquitetura, as VPCs são conectadas umas às outras usando o IBM Cloud® Transit Gateway. Um conjunto de microsserviços compartilhados é acessado por meio de nomes de host registrados no IBM Cloud® DNS Services. Cada VPC é gerenciada por uma equipe separada, isolada pelo IBM Cloud® Identity and Access Management. Opcionalmente, um IBM Cloud® Load Balancer pode ser usado para dimensionar o microsserviço compartilhado.

Objetivos

  • Saiba como isolar a infraestrutura usando o IAM e os grupos de recursos
  • Crie as VPCs e os recursos associados, como as sub-redes, as ACLs de rede, os grupos de segurança e as instâncias.
  • Endereçar microsserviços por resolução de nome DNS usando DNS Services.
  • Conecte as VPCs via Transit Gateway.
  • Configure de forma transparente um Load Balancer para um aplicativo.

Arquitetura abstrata:

Arquitetura*Diagrama de
do

No diagrama acima o usuário final está acessando os aplicativos. Os aplicativos estão aproveitando os microsserviços compartilhados. A empresa tem equipes separadas do DevOps que possuem application1, application2 e compartilhado. Uma equipe de rede se concentra na conectividade e na segurança de rede. As equipes de DevOps gerenciam Instâncias de Serviço Virtual, as VSIs, usadas para implementar os serviços que elas criam e suportam.

Arquitetura concreta

A arquitetura a seguir implementa os requisitos de isolamento e de conectividade estabelecidos pela empresa. Observe que application1, compartilhado e application2 são VPCs. A zona única e a sub-rede em cada VPC podem ser expandidas para uma implementação multizona mais detalhada ao longo do tempo.

Arquitetura do tutorial
Arquitetura do tutorial

Antes de Iniciar

Este tutorial requer:

  • IBM Cloud CLI com estes plugins:
    • Transit Gateway (tg)
    • IBM Cloud VPC (vpc-infrastructure)
    • DNS Services (dns)
  • git para clonar o repositório de código-fonte.
  • terraform para executar os comandos do Terraform.

Você encontrará instruções para baixar e instalar essas ferramentas para o seu ambiente operacional no guia Getting started with solution tutorials.

Além disso:

  • Verifique as permissões do usuário. Certifique-se de que a sua conta de usuário tem permissões suficientes para criar e gerenciar os recursos de VPC, crie um IBM Cloud® Transit Gateway e crie serviços do IBM Cloud® Transit Gateway. Consulte a lista de permissões necessárias para a VPC. Também será necessária a capacidade de criar grupos de recursos e recursos do IAM como grupos de acesso, políticas, IDs de serviços, ...
  • Você precisa de uma chave SSH para se conectar aos servidores virtuais. Se você não tiver uma chave SSH, consulte as instruções para criar uma chave para a VPC.

Planejar o ambiente de gerenciamento de acesso e de identidade

A equipe do administrador permitirá que as outras equipes administrem seus recursos o máximo possível. A equipe do administrador gerenciará os usuários e controlará o acesso, mas não criará e destruirá os recursos mostrados no diagrama de arquitetura.

Editor, Operador, Visualizador e Gerenciador são funções de acesso do IAM. Cada serviço define o significado exato das funções e as ações associadas.

Equipes:

  • Administrador - definir a estrutura da conta, como os grupos de recursos, os grupos de acesso, os usuários, as funções.
  • Rede - criar recursos de rede como serviço, VPC e sub-redes DNS Services, Transit Gateway.
  • Compartilhado - criar os dispositivos de instância de servidor virtual e de bloco na VPC compartilhada. Criar os registros DNS para os serviços compartilhados.
  • Application1 - criar os dispositivos de instância de servidor virtual e de bloco na VPC do application1
  • Application2 - criar os dispositivos de instância de servidor virtual e de bloco na VPC do application2.

IAM conceitual

Equipe de rede

Um modelo de propriedade da equipe conceitual foi implementado. A equipe da rede administra todos os recursos da rede e, consequentemente, a maior parte do que é mostrado no diagrama.

Arquitetura com foco na equipe de rede
Arquitetura com foco na equipe de rede

Equipe compartilhada

A equipe compartilhada cria a instância de servidor virtual em sua VPC isolada. Além disso, a equipe precisa gravar registros no serviço DNS, pois os endereços IP dos VSIs são determinados no momento da criação. O acesso de operador à VPC, às sub-redes e aos grupos de segurança é necessário para criar uma instância de servidor virtual.

Arquitetura com foco na equipe compartilhada
Arquitetura com foco na equipe compartilhada

As equipes application precisam do mesmo acesso que a equipe compartilhada, exceto o acesso do gerenciador ao DNS Services.

Acesso da equipe do aplicativo:

Arquitetura com foco na equipe do Aplicativo
Arquitetura com foco na equipe do Aplicativo

Arquitetura do IAM

Se você tiver um bom entendimento de grupos de recursos e de grupos de acesso do IAM, será possível conferir rapidamente esta seção e iniciar as etapas de criação de recursos.

Grupos de acesso

Um grupo de acesso será criado para cada equipe. As políticas de acesso são incluídas nos grupos de acesso e, em seguida, os usuários (membros da equipe) são incluídos no grupo de acesso para conceder acesso.

A instância de serviço do Transit Gateway é gerenciada exclusivamente pela equipe de rede. O acesso de editor é necessário para a criação. O acesso do gerenciador à instância criada permite que as VPCs sejam conectadas ao Transit Gateway.

Neste exemplo, uma única zona DNS, widgets.example.com, será criada e o acesso à zona DNS será permitido a todas as VPCs. A instância de serviço DNS é criada pela equipe de rede (função do editor) e a permissão das zonas requer a função de gerenciador. A resolução de DNS em tempo de execução em uma instância em um VPC não requer o acesso IAM. A equipe compartilhado precisa listar as instâncias de DNS (função Visualizador) e incluir um registro de A ou CNAME (função Gerenciador).

Os serviços de infraestrutura (IS) da VPC consistem em cerca de 15 diferentes tipos de serviço. Alguns são de interesse apenas da equipe de rede, como as ACLs (listas de controle de acesso) de rede. Outros são de interesse apenas das equipes de microsserviços, como as instâncias VSI. Mas alguns são editados pela equipe de rede e operados pela equipe de microsserviços, como as sub-redes. A equipe de rede criará a sub-rede e uma equipe de microsserviço criará uma instância em uma sub-rede. Para a finalidade deste tutorial, os tipos de serviço IS da VPC, o Transit Gateway e o DNS são resumidos para cada grupo de acesso na tabela abaixo. Os conteúdos da tabela são as funções necessárias.

Funções necessárias designadas para equipes com base em suas responsabilidades
Serviço rede compartilhado aplicativo
Transit Gateway Editor, Gerenciador
DNS Editor, Gerenciador Visualizador, Gerenciador
IS: ACL de rede Editor
IS: Instância, Volume, IP flutuante, Chave SSH, Imagem, Balanceador de carga Editor Editor
IS: VPC, Sub-rede, Grupo de segurança Editor Operador Operador

Grupos de recursos

A equipe compartilhada e a equipe de rede agora estão bem separadas. Mas como o Application1 é isolado do Compartilhado e do Application2? Eles são Editor para os mesmos tipos de serviços.

É aqui que os grupos de recursos podem ajudar. Cada instância de serviço (ou seja, recurso) tem um atributo de grupo de recursos que é inicializado na criação e não pode ser alterado. Em outras palavras, cada recurso está em um grupo de recursos.

Diagrama do grupo de recursos:

Diagrama do Grupo de Recursos
Diagrama do Grupo de Recursos
..

Cada equipe de microsserviço terá permissão de acesso no grupo de recursos correspondente. A equipe da rede terá acesso a todos esses grupos de recursos.

O grupo de recursos de rede contém Transit Gateway e o serviço DNS. A equipe da rede tem acesso a esses recursos. A equipe compartilhada terá acesso de gerente ao serviço de DNS. A equipe compartilhada precisa gravar as entradas de DNS para os serviços compartilhados.

Mais adiante no tutorial, depois que todos os recursos tiverem sido criados, pode ser informativo abrir a lista de recursos no console IBM Cloud. É possível filtrar por grupo de recursos.

Criar um ambiente de trabalho local

Todas as operações serão executadas em um shell bash e com o uso dos comandos terraform e ibmcloud. Você encontrará instruções para baixar e instalar essas ferramentas para o seu ambiente operacional no guia Getting started with solution tutorials.

  1. Git clone o repositórioa seguir:

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

    Verifique se há um diretório para cada equipe (ignorando application2 por enquanto):

    • admin /
    • rede /
    • compartilhado /
    • application1/
  2. Crie o arquivo terraform.tfvars :

    cp terraform.tfvars.template terraform.tfvars
    

    Em seguida, edite terraform.tfvars para configurar essas variáveis:

    • ssh_key_name- é necessário especificar uma chave SSH existente na ibm_region, conforme especificado na seção Antes de começar acima.
    • ibm_region- substitua o valor padrão, us-south, se necessário. O comando da CLI ibmcloud regions exibirá todas as regiões possíveis.
    • basename- substitui o valor padrão, widget0, por um nome com 7 caracteres ou menos, se necessário. A maioria dos recursos criados usará isso como prefixo de nome.
    • Não descomente o transit_gateway ou shared_lb neste momento.
  3. Somente usuários do Windows: se o git não criar o link simbólico no seu computador Windows, será necessário copiar o conteúdo do arquivo para as pastas da equipe:

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

Uma Nota sobre se tornar um membro da equipe

É possível preencher o grupo de acesso de cada equipe com os usuários. Mas, em vez de criar usuários, este tutorial criará um ID de serviço no grupo de acesso de cada equipe. Você é o administrador e se tornará um membro dos diferentes grupos de acesso usando a chave API para o ID de serviço da equipe. Os nomes de ID de serviço são ${basename}-x, em que x é network, shared, application1 e application2. Posteriormente, você preencherá um arquivo local.env em cada diretório da equipe com conteúdos semelhantes a este:

export TF_VAR_ibmcloud_api_key=0thisIsNotARealKeyALX0vkLNSUFC7rMLEWYpVtyZaS9

Em cada etapa, quando você cd entrar em um diretório de equipe, será lembrado de executar: source local.env

O Terraform será usado para criar os recursos. Abra o admin/main.tf e observe a cláusula provider ibm e a referência para o ibmcloud_api_key inicializado por meio da variável de ambiente:

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

Se você precisar usar a IBM Cloud CLI como membro da equipe:

ibmcloud login --apikey $TF_VAR_ibmcloud_api_key

Criar os recursos ativados para IAM (equipe do administrador)

A equipe do administrador precisará ter acesso de Administrador aos recursos ativados para IAM na conta usada neste tutorial. Consulte Como atribuir acesso total de usuário como administrador de conta?. A equipe de administradores será responsável pela criação dos recursos do IAM. As instruções abaixo usam o comando ibmcloud iam api-key-create para criar uma chave de API para o administrador. A chave de API será usada pelo Terraform para executar tarefas em seu nome.

As chaves PI são o mesmo que uma senha para sua conta. Mantenha as chaves de API seguras.

  1. Inicialize e verifique a variável shell do nome base. Verifique se corresponde ao nome base no arquivo terraform.tfvars:

    eval $(grep basename terraform.tfvars | sed -e 's/  *//g' -e 's/#.*//')
    echo basename=$basename
    
  2. Mude de diretório, gere e origine sua chave de API pessoal em local.env. Quando o Terraform for chamado, ele se tornará você. O Terraform será o administrador:

    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. A aplicação do arquivo de configuração do main.tf Terraform cria os seguintes recursos:

    • Grupos de recursos para cada equipe
    • Grupos de acesso para cada equipe e um ID de serviço em cada grupo de acesso
    • Políticas de grupo de acesso para os grupos de recursos
    • Políticas de grupo de acesso para os recursos
    terraform init
    terraform apply
    
  4. Verifique se os recursos foram criados:

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

    A saída se assemelhará a algo assim:

    $ 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. Opcionalmente, navegue até a conta Grupos de recursos e localize os grupos de recursos.

  6. Opcionalmente, navegue até Grupos de acesso para ver os grupos de acesso, clique em um grupo de acesso e, em seguida, clique no painel IDs de serviço na parte superior para ver o ID de serviço criado.

Criar VPCs e DNS (equipe de rede)

A equipe de rede criará os recursos de rede para a correspondência com a arquitetura, garantindo que os objetivos de conectividade sejam atendidos e que as equipes sejam isoladas em sua VPC. Eles não querem controlar os detalhes das instâncias de VPC. É provável que o número de aplicativos, o tamanho dos computadores, os registros de DNS para microsserviços etc. estejam em constante fluxo e não sejam uma preocupação da equipe de rede.

A equipe do Administrador proporcionou a eles apenas a quantidade certa de permissões para criar os recursos is da VPC, o DNS Services e o serviço Transit Gateway.

  1. Mude de diretório, gere uma chave de API no local.env e torne-se um membro do grupo de acesso à rede:

    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. Opcionalmente, abra o arquivo variables_network.tf e observe a especificação do bloco CIDR e o layout da zona. No trecho abaixo, observe que shared e application1 são especificados sem sobreposição de endereços 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",
         ...
    

    O Transit Gateway terá uma conexão a cada VPC e rotas de tráfego com base nas faixas de CIDR. Assim, evitar as sobreposições garantirá o sucesso.

  3. Crie os recursos:

    terraform init
    terraform apply
    
  4. Listar os recursos da VPC

    Os recursos da VPC criados são resumidos pela saída do comando de sub-redes, mostrado abaixo, editado para brevidade. Observe as três VPCs, os blocos CIDR não sobrepostos e a associação aos grupos de recursos:

    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
    

    A saída será semelhante a esta:

    $ 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. Opcionalmente, navegue até Virtual Private Clouds e encontre as VPCs, sub-redes e todos os outros recursos criados acima.

  6. main.tf, investigue a configuração do Terraform para entender a inicialização DNS Services. A instância e a zona do DNS Services foram criadas com o fragmento do 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"
    }
    

    Em seguida, a zona é incluída em uma VPC como uma rede permitida:

    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. Listar a configuração do DNS. Uma instância do DNS Services foi criada. A zona widgets.example.com foi criada. Por fim, a zona foi adicionada a todas as VPCs.

    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
    

    O resultado será semelhante a este:

    $ 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. Opcionalmente, navegue até a lista de recursos e localize o DNS Services, clique nele e investigue.

Crie o microsserviço compartilhado e o registro DNS associado (Equipe compartilhada)

  1. Mude de diretório, gere uma chave de API no local.env e torne-se um membro do grupo de acesso compartilhado:

    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. Opcionalmente, neste ponto, aprofunde-se no código-fonte do Terraform. A equipe compartilhada fornecerá microsserviços. Embora a equipe de rede já tenha criado a VPC compartilhada e alguns recursos de rede, a equipe compartilhada criará a instância e escolherá o perfil da instância. Um script de configuração do Linux e um aplicativo de demonstração simples são fornecidos no atributo user_data e discutidos na seção Equipe de aplicativo abaixo.

    Em main.tf, observe estes dois recursos:

    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
    }
    

    O local.network_context acima é a saída gerada pela equipe de rede, especificamente para a equipe compartilhada.

  3. Crie os recursos compartilhados:

    terraform init
    terraform apply
    
  4. Opcionalmente, navegue até as instâncias de servidor virtual para VPC e localize a instância compartilhada. Clique sobre ele e verifique o seguinte:

    • A instância não tem conectividade de entrada da Internet pública (verifique os grupos de segurança)
    • Localize o endereço IP privado
  5. Opcionalmente, navegue até a lista de recursos e localize o DNS Services, clique nele e localize o registro DNS com o nome compartilhado. Observe que o Valor é o endereço IP privado da instância.

Criar um microsserviço voltado para o público para um aplicativoApplication1 Equipe)

  1. Mude o diretório, gere uma chave de API em local.env e torne-se um membro do grupo de acesso 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
    

    Os recursos da equipe application1 são muito semelhantes ao da equipe compartilhada. Na verdade, eles são um pouco mais simples, pois não é necessário colocar registros no DNS Services. O aplicativo usa o endereço http://shared.widgets.example.com para acessar o microsserviço compartilhado.

  2. Opcionalmente, investigue o código-fonte que inicializa a instância CentOS. Ele foi capturado em um módulo do Terraform compartilhado por todas as equipes durante esse estágio exploratório.

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

    Explicação detalhada:

    • O Node.js é instalado com os comandos curl e yum
    • O aplicativo Node.js é colocado em /app.js.
    • Um serviço systemctl é criado para app.js
    • O serviço é iniciado
  3. Opcionalmente, investigue os conteúdos de app.js. Ele tem duas seções particularmente interessantes. Primeiro, há um link /info que retorna uma descrição da instância que está executando o aplicativo. ../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
    

    Em segundo lugar, o link /remote chama o IP de um servidor remoto e retorna a descrição desse servidor remoto juntamente com os endereços remote_url e remote_ip usados para acessar o servidor remoto.

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

    No nosso caso, o REMOTE_IP será shared.widgets.example.com devido ao seguinte em common/user_data_app/main.tf:

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

    E de volta em application1/main.tf:

    module user_data_app {
      source    = "../common/user_data_app"
      remote_ip = "shared.widgets.example.com"
    }
    
  4. Crie os recursos:

    terraform init
    terraform apply
    

    Os resultados se parecem com o seguinte:

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

    Tente os dois comandos de curl (test_info, test_remote) que foram sugeridos acima. Copie as instruções de sua saída.

    curl 52.116.140.202:3000/info
    

    O primeiro resulta em algo como o que foi capturado abaixo:

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

    Em seguida, tente o segundo comando (a partir da sua saída):

    curl 52.116.140.202:3000/remote
    

    Espere, pois o segundo comando curl não funcionou. Fixe-o na próxima etapa. Lembre-se desses comandos curl, pois você os usará novamente em breve.

Criar Transit Gateway

IBM Cloud Transit Gateway é um serviço de rede usado para interconectar recursos de VPC IBM Cloud Fornecendo escalabilidade dinâmica, alta disponibilidade e a tranquilidade de saber que os dados não estão atravessando a Internet pública. Anteriormente, os blocos CIDR para cada uma das VPCs foram escolhidos sem sobreposição para permitir que o Transit Gateway roteie os pacotes por endereço IP.

  1. Mude o diretório e torne-se um membro do grupo de rede (use a chave de API existente):

    cd ../network
    source local.env
    
  2. Opcionalmente, investigue os arquivos do Terraform. Abra o arquivo main.tf e você notará os recursos do Transit Gateway (ibm_tg). Cada um tem um count = var.transit_gateway ? 1 : 0. Esta é uma construção do Terraform que cria uma matriz de recursos de comprimento 1 ou 0 com base no valor de transit_gateway. Uma matriz de comprimento 0 não resultará em nenhum recurso. Por exemplo:

    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. Edite o arquivo terraform.tfvars e descomente a linha transit_gateway = true para ativar o provisionamento de Transit Gateway.

  4. Aplicar a mudança

    terraform apply
    
  5. Imprima o Transit Gateway usando os comandos abaixo.

    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
    

    Observe as três conexões de VPC na saída. Ela será semelhante a esta:

    $ 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. Opcionalmente, navegue no Transit Gateway e localize o gateway criado acima.

  7. Execute o comando curl acima que falhou anteriormente para verificar se há um caminho da VPC application1 para a VPC compartilhada. Ele se parecerá com o seguinte:

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

Insira um Load Balancer e substitua o registro DNS

Incluindo um Balanceador de Carga na arquitetura
Incluindo um Balanceador de Carga na arquitetura

  1. Mude o diretório e torne-se um membro do grupo de acesso compartilhado (use a chave de API existente):

    cd ../shared
    source local.env
    
  2. Opcionalmente, investigue os arquivos de configuração do Terraform. O serviço Load Balancer for VPC distribui o tráfego entre várias instâncias de servidor na mesma região de sua VPC. A equipe compartilhada pode balancear a carga entre várias instâncias. Por enquanto, o conjunto de balanceadores de carga terá apenas a instância única criada anteriormente. Consulte o lb.tf para ver a implementação. No recurso ibm_is_lb, use a cláusula dns para identificar a zona de DNS privada para colocar o endereço DNS do balanceador de carga:

    resource "ibm_is_lb" "shared_lb" {
      ...
      dns {
        instance_crn = local.network_context.dns.crn
        zone_id      = local.network_context.dns.zone_id
      }
    }
    
  3. Forneça um registro CNAME do DNS shared.widgets.example.com para identificar o balanceador de carga, para que os aplicativos continuem a funcionar sem mudanças de código-fonte:

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

    O mesmo count = var.shared_lb ? 1 : 0 é usado O nome do host do balanceador de carga será algo semelhante a b7911a41-us-south.widgets.example.com O registro CNAME será usado pelos aplicativos

  4. Edite o arquivo terraform.tfvars e descomente o shared_lb = true. Em seguida, aplique as alterações:

    terraform apply
    
  5. Execute o comando curl .../remote da seção application1 anterior (ignore a saída que acabou de ser gerada para o microsserviço compartilhado). Observe que o remote_ip é 10.0.1.4, o balanceador de carga, e o remote_info é 10.0.0.4, a instância. Faça Curl mais algumas vezes e observe que o remote_ip do balanceador de carga pode mudar.

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

Criar um microsserviço voltado para o público para um aplicativoApplication2 Equipe)

O segundo ambiente de equipe do aplicativo é idêntico ao primeiro. Opcionalmente, crie application2 modificando application1.

  1. Insira o diretório ./application1 e crie o diretório 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. Mude de diretório, gere uma chave de API no local.env e torne-se um membro do grupo de acesso 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. Crie os recursos:

    terraform init
    terraform apply
    
  4. Teste os comandos curl

Remover recursos

  1. Destrua os recursos. Você pode alterar cd) para os diretórios da equipe em ordem e executar source local.env; terraform destroy. A ordem é application2, application1, shared, network e admin. Há também um script que fará isso para você:

    cd ..
    ./bin/destroy.sh
    

Expandir o tutorial

Outras considerações

  • A equipe do Aplicativo está fornecendo acesso a ele por meio de um endereço IP flutuante. Considere conectá-lo ao IBM Cloud Internet Services. Ele pode gerenciar o DNS público e fornecer segurança. Implementar cargas de trabalho isoladas em vários locais e zonas tem um exemplo.
  • A equipe de aplicativos pode ser dimensionada horizontalmente usando um balanceador de carga como a equipe compartilhada.
  • A equipe compartilhada pode adicionar instâncias adicionais ao balanceador de carga adicionando instâncias ao shared/main.tf.
  • A equipe compartilhada poderia mudar sua plataforma de implementação para o Kubernetes.

Continuous Delivery

  • Atualmente, a instalação do software ocorre quando a instância da VPC é criada. A entrega de novas versões de software para produção não foi considerada.
  • Para microsserviços compartilhados, um novo VSI poderia ser criado com uma nova versão e, após a verificação, o DNS poderia ser ajustado ou o balanceador de carga compartilhado poderia ser usado para mudar para a nova versão.

Automação, preparação e desenvolvimento

  • Para produção, cada equipe pode ter seu próprio espaço de trabalho Schematics. Com o Schematics, as configurações do Terraform podem ser executadas diretamente na nuvem na qual o estado e a saída podem ser compartilhados.
  • Os scripts do Terraform podem ser ajustados para permitir ambientes de preparação e de desenvolvimento. Coloque esses ambientes em novas contas.
  • Um ambiente de implementação contínua pode ser construído para mover o código e os ambientes ao longo do desenvolvimento, da preparação e da produção. A recuperação é necessária? Como isso seria realizado?

Conclusões

A arquitetura de um sistema é influenciada pela contenção e propriedade de recursos em nuvem. É importante que os arquitetos de todos os aspectos do sistema contribuam com seus interesses para a arquitetura. Toda equipe precisa ter a capacidade de controlar os recursos que produz e libera. O isolamento reduzirá a probabilidade de problemas e conterá o raio de alcance quando os problemas ocorrerem.