Participe da Maratona Behind the Code! Prêmios e desafios incríveis te esperam, não perca! Inscreva-se aqui

Terraform-as-a-Service – Implante de forma automatizada um microserviço no IBM Cloud kubernetes e API Gateway

Amigo leitor, quero começar este artigo explicando que configurar manualmente a infraestrutura para aplicativos nativos em nuvem é moroso e sujeito a erros. A automação reduz os erros, mas as soluções de automação típicas são específicas de cada fornecedor da nuvem e exigem habilidades especializadas.

Terraform é um serviço totalmente de código aberto, para gerenciar e fornecer recursos de nuvem, como máquinas virtuais, serviços cognitivos Watson e clusters de contêiner. Todos usando as melhores práticas de “Infraestrutura como Código”.

A infraestrutura como código reduz custos, acelera a execução da entrega e diminui o risco. Documentando e gerenciando a infraestrutura, usando as mesmas ferramentas utilizadas na engenharia de software para documentar, versionar e gerenciar código.

Introdução

Com este laboratório, você implantará um aplicativo de microsserviços Python e gerenciará um cluster Kubernetes na IBM® Cloud Kubernetes Service (IKS). Vamos automatizar a implantação, operação, escalonamento e monitoramento de aplicativos em contêineres, em um cluster a partir do Container Registry.

Neste tutorial, você atua como um desenvolvedor. Assim, deverá configurar um cluster Kubernetes customizado, que é usado para implantar e testar um aplicativo de microsserviços backend, escrito em Python. Vamos criar um API Gateway, para que seja chamado a partir de um frontend e efetue o target no serviço kubernetes, usando o serviço nodeport. O modelo do trabalho será em REST. Todos são executados no contêiner Docker, gerenciado pelo Kubernetes e exposto pelo API Gateway.

Vou demonstrar, também, o mesmo provisionamento na IBM Cloud e na AWS, em relação ao API Gateway. Será bem legal, galera!

Arquitetura da solução proposta no Laboratório do artigo

Objetivos

  • Vamos criar um cluster com 1 worker pool e 1 worker node.
  • Instale, primeiramente, caso não os tenha, os CLIs, para executar comandos Kubernetes, gerenciar imagens Docker na IBM Cloud Container Registry e no Terraform.

Pré-requisitos para instalação dos CLI's

Pré-requisitos

  • Uma conta gratuita da nuvem da IBM.
  • Uma conta gratuita da nuvem da AWS.

CLI da IBM Cloud – MacOS

  1. Faça o download e instale a CLI da IBM Cloud em:
    https://github.com/IBM-Cloud/ibm-cloud-cli-release/releases/latest.
  2. Verifique a instalação com:
    ibmcloud version

Docker – MacOS

  1. Se você não tiver uma, inscreva-se para uma conta grátis em:
    https://hub.docker.com/signup.
  2. Faça o download e instale o Docker Desktop no Mac em:
    https://docs.docker.com/docker-for-mac/install/.
  3. Verifique a instalação com:
    docker --version

kubectl – MacOS

  1. Faça o download do kubectl em:
    https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-on-macos.
  2. Torne o binário do kubectl executável.
    chmod +x ./kubectl
  3. Mova o binário para o seu PATH.
    sudo mv ./kubectl /usr/local/bin/kubectl
  4. Verifique a instalação com:
    kubectl version --client=true

Terraform – MacOS

  1. Faça o download do terraform em:
    https://www.terraform.io/downloads.html.
  2. Descompacte o archive transferido por download.
  3. Mova o binário terraform para o seu PATH.
    sudo mv ./terraform /usr/local/bin/terraform
  4. Verifique a instalação com:
    terraform version

CLI da AWS – MacOS

  1. Faça o download e instale a CLI AWS Cloud em:
    https://docs.aws.amazon.com/pt_br/serverless-application-model/latest/developerguide/serverless-sam-cli-install-mac.html
  2. Ou execute: $ brew install aws-sam-cli
  3. Verifique a instalação com o comando abaixo e verifique as credenciais logo após:

       
    sam –version
    aws configure
    cat /˜/.aws/credentials
    [default]
    aws_access_key_id = AKIAR5M6LFJ
    aws_secret_access_key = fGJCS1aF41bL
       
     

Hands On – Execute e registre um aplicativo de microsserviços em contêiner, na plataforma sem servidor, gerenciada pelo IBM Cloud Kubernetes

  1. Primeiramente, crie um arquivo de configuração do Terraform, especificando os recursos da IBM Cloud, que você deseja provisionar. Salve este arquivo com a extensão .tf, exemplo: 1-provider.tf. Este arquivo se faz obrigatório no momento que executarmos o />terraform init.

       
    terraform {
    required_providers {
     ibm = {
       source  = "IBM-Cloud/ibm"
       version = ">= 1.26.0"
     }
    }
    }
    provider "ibm" {
    region = var.region
    }
       
     
  2. Crie um arquivo com a declaração das variáveis para o uso de chaves, recursos e módulos, que tenha necessidade em todo o seu projeto. Exemplo: 2-variables.tf. Notem que a variável region é utilizada no primeiro arquivo 1-provider.tf.

       
    variable "region" {
    description = "Define what region the instance will be deployed"
    default     = "us-south"
    }
    variable "action_type" {
    type        = string
    description = "Update actions manage,unmanage,share,unshare"
    default     = "unshare"
    }
    variable "cr_namespace_name" {
    type = string
    default = "bff-terra-erp"
    }
       
     
  3. Crie agora um arquivo 3-container.tf, que será responsável pelo resource-group, o namespace e, por último, a execução do comando para criação da imagem Docker, com o código da aplicação, que no exemplo usaremos o Python. Tudo isso ocorre antes de implantar (deploy) no cluster kubernetes. O objetivo será criar um repositório de imagens privado na IBM Cloud Container Registry, para armazenar suas imagens.

       
    data "ibm_resource_group" "resource_group" {
    name = "Default"
    }
    resource "ibm_cr_namespace" "rg_namespace" {
    name              = var.cr_namespace_name
    resource_group_id = data.ibm_resource_group.resource_group.id
    }
    resource "null_resource" "create_build_img" {
    provisioner "local-exec" {
     command = "ibmcloud cr build -t us.icr.io/${ibm_cr_namespace.rg_namespace.name}/python-docker-v2 /Users/fabrizio.rodriguesibm.com/Documents/cloudArchitect/python/test1/imagem/backforfront-api-generic/."
    } }
    Obs: notem que a variável cr_namespace_name está declarada no arquivo 2-variables.tf.

    Repositório do Container Registry na IBM Cloud

    O plano acima, no final, irá implantar o recurso de acordo com a imagem. O recurso do template, do terraform ibm_resource_group, configura o item na aba Grupo de Recursos, com o nome Defaulf. O recurso do template, do terraform ibm_cr_namespace, configura o namespaces de acordo com a aba Nome. E, por último, o mais legal, é o recurso do template do terraform local-exec, que implantará a imagem no repositório, conforme a figura acima.

    Para executá-la, é necessário informar a região, o namespace e o nome da tag: us.icr.io/${ibm_cr_namespace.rg_namespace.name}/python-docker-v2. Não esqueça de fornecer o caminho do seu Dockerfile.

    3.1 Demonstração do código em Python e o Dockerfile utilizado para criação da imagem. A imagem listada também é apresentada depois de criada.

    Demonstração do código em Python e o Dockerfile utilizado para criação da imagem

    Logo, será apresentado a sequência de comandos CLI, para execução do plano!

  4. Crie o próximo arquivo 4-kube.tf. Este fará a criação do cluster do kubernetes com 1 worker nodes no worker pool padrão e a ligação do serviço no cluster. Informaremos qual a infraestrutura utilizada, a região e o plano. No exemplo, utilizaremos a infraestrutura clássica.

       
    resource "ibm_container_cluster" "testacc_cluster" {
    name            = "my_cluster3"
    datacenter      = "dal10"
    hardware        = "shared"
    machine_type    = "free"
    }
    \/\/ibmcloud iam orgs --guid para obter o id 
    data "ibm_container_cluster_config" "cluster_config" {
    cluster_name_id = ibm_container_cluster.testacc_cluster.name
    }
    resource "null_resource" "create_cluster_img" {
    provisioner "local-exec" {
     command = <<EOF
     export KUBECONFIG="${data.ibm_container_cluster_config.cluster_config.config_file_path}"
     kubectl config current-context
     kubectl create deployment python-docker-v3-deployment --image=us.icr.io/${ibm_cr_namespace.rg_namespace.name}/python-docker-v2:latest
     kubectl expose deployment/python-docker-v3-deployment --type=NodePort --port=5000 --name=python-docker-v3-service --target-port=5000
     kubectl describe service python-docker-v3-service
     ibmcloud ks worker ls --cluster ${ibm_container_cluster.testacc_cluster.name}
    
    EOF } depends_on = [ibm_container_cluster.testacc_cluster] }
    O recurso ibm_container_cluster configura o cluster com as características abaixo.

    Repositório do Kubernetes na IBM Cloud

    Nós de trabalho do Kubernetes, na IBM Cloud, representando o status dos serviços

    No plano acima, informei o datacenter em Dallas. Porém, como a infraestrutura é modo clássica, a IBM Cloud pode provisionar na localização que estiver disponível. Semelhante à criação do container, utilizei o recurso do template, do terraform “local-exec”, para implantar o app no cluster.

    Existem diferentes maneiras de tornar seu aplicativo acessível a partir da internet. Para escolher a melhor opção de rede para seu aplicativo, você pode seguir a árvore de decisão disponível aqui.

    Depois de implantado, faço um describe no serviço do kubernetes para obter a porta que o nodeport deixará exposto. E faço um ls no worker do cluster para obter o ip público que o serviço/deployments estarão expostos:

    Resultado descrito após o deployment do Kubernetes, demonstrando a porta exposta do serviço Nodeport

    Resultado descrito após o deploy do cluster do Kubernetes, com o IP público que será acessado

    4.1 Com isso, nós temos o seguinte endpoint: http://169.57.99.4:32226.

  5. Agora, vamos executar os comandos para gerar o plano da infraestrutura e ter o resultado acima — ou seja, a infraestrutura criada. É necessário efetuar o login na IBM Cloud com um usuário ativo, pois executaremos o recurso do template do terraform local-exec. É importante instanciar o IBM Cloud API Key no ambiente, para que o plugin do provider seja executado no $terraform init.

       
    $ ibmcloud login –sso
    $ ibmcloud target -g Default
    $ export IC_API_KEY={chave api-key}
    $ export IAAS_CLASSIC_USERNAME="{id user ibm cloud}"
    $ terraform init
    $ terraform plan
    $ terraform apply -auto-approve
       
     
    Utilize o comando $terraform init somente na primeira vez. Depois, sempre que efetuar os ajustes, apenas execute o plano e o apply.

    Para remover toda a infra, execute $terraform destroy.

    O terraform tem o controle do ambiente a partir do arquivo terraform.tfstate.

  6. Hands On – Parte 2

    Agora, vamos criar o recurso do template do Terraform na IBM Cloud API Gateway, na Amazon Web Services API Gateway e mostrar as diferenças entre os provedores.

    A ideia é configurarmos um proxy que redirecione para o endpoint, criado no IKS (http://169.57.99.4:32226). Vou demonstrar, também, como configurar os recursos e os verbos REST API, a partir de uma especificação OpenAPI.

  7. Hands On – IBM Cloud API Gateway

    Novamente: em outra pasta, crie um arquivo de configuração do Terraform, especificando os recursos da IBM Cloud que você deseja provisionar. Salve este arquivo com a extensão .tf, exemplo: 1-provider.tf. Este arquivo se faz obrigatório no momento que executarmos o />terraform init.

       
    terraform {
    required_providers {
     ibm = {
       source  = "IBM-Cloud/ibm"
       version = ">= 1.26.0"
     }
    }
    }
    provider "ibm" {
    region = var.region
    }
       
     
  8. Crie um arquivo com a declaração das variáveis para o uso de chaves, recursos e módulos, que tenha necessidade em todo o seu projeto. Exemplo: 2-variables.tf. Notem que a variável region é utilizada no primeiro arquivo 1-provider.tf.

       
    variable "region" {
    description = "Define what region the instance will be deployed"
    default     = "us-south"
    }
    variable "service_name" {
    type        = string
    description = "Service instance name"
    default = "API-Terraform"
    }
    variable "managed" {
    type        = string
    description = "Indicates if endpoint to be online or offline"
    default     = "true"
    }
    variable "action_type" {
    type        = string
    description = "Update actions manage,unmanage,share,unshare"
    default     = "unshare"
    }
       
     
  9. Crie um arquivo com o nome 3-apigw.tf, que será utilizado para aplicar o plano de configuração do API Gateway. Os parâmetros location e plan podem sofrer alteração de acordo com o recurso que esteja criando. Como estou usando o plano Lite na IBM Cloud, então escolhi conforme abaixo. O nome do service: mantenha api-gateway para que o provider entenda que estamos criando o API gateway no API Management, na IBM Cloud.
    Outro ponto interessante é o parâmetro managed, que terá a função de ativar a API e criar a URL que será exposta.
    A API proxy configurada receberá o nome conforme o parâmetro name e será implementada conforme o arquivo .json, com as especificações OpenAPI.

       
    \/\/ provision apigateway resource instance
    resource "ibm_resource_instance" "apigateway" {
    name     = var.service_name
    location = "global"
    service  = "api-gateway"
    plan     = "lite"
    }
    \/\/ provision endpoint resources for a directory of api douments..
    resource "ibm_api_gateway_endpoint" "routeFmsApi" {
    service_instance_crn = ibm_resource_instance.apigateway.id
    managed              = var.managed
    name                 = "routeFmsApi"
    open_api_doc_name    = "./apigw.json"
    //type                 = var.action_type //required only when updating action
    }
       
     
    O serviço criado conforme a tela abaixo está definido com o nome declarado no parâmetro da variável var.service_name.

    Repositório do serviço API Gateway na IBM Cloud

    A API criada conforme a tela abaixo está definida com o nome declarado no parâmetro name, do recurso ibm_api_gateway_endpoint- routeFmsApi.

    API Proxy exposta e a url publicada após a execução do plano do Terraform

  10. Crie o arquivo .json com a especificação OpenAPI, que será utilizada para criação da API.

    Definição rápida:
    A especificação OpenAPI (OAS) define uma interface padrão, independente de linguagem para APIs RESTful, que permite que humanos e computadores descubram e entendam os recursos do serviço sem acesso ao código-fonte, documentação ou por meio de inspeção de tráfego de rede.
    Quando definido corretamente, um consumidor pode entender e interagir com o serviço remoto, com uma quantidade mínima de lógica de implementação.

    O Documento OpenAPI é um documento (ou conjunto de documentos) que define ou descreve uma API.

  11. O parâmetro open_api_doc_name será aplicado a partir do documento apigw.json abaixo. Você declara o nome do recurso a partir do basePath, os verbos a partir dos paths, e os parâmetros de integração do proxy a partir de x-ibm-configuration. Para habilitar o CORS, configure com um parâmetro booleano. Os parâmetros de integração estão contidos em invoque. Note que ao declararmos em verb o parâmetro keep, a integração irá manter o verbo (GET, PUT e POST), chamado no recurso principal.

      
    {
    "swagger": "2.0",
    "info": {
    "version": "1.0",
    "title": "poc-routeapi"
    
    }, "schemes": [
    "https"
    
    ], "consumes": [
    "application/json"
    
    ], "produces": [
    "application/json"
    
    ], "paths": {
    "/": {
        "get": {
            "description": "Default get resource for endpoint",
            "responses": {
                "200": {
                    "description": "A successful invocation response"
                }
            }
        },
        "post": {
            "description": "Default post resource for endpoint",
            "responses": {
                "200": {
                    "description": "A successful invocation response"
                }
            }
        },
        "options": {
            "description": "Default options resource for endpoint",
            "responses": {
                "200": {
                    "description": "A successful invocation response"
                }
            }
        }
    }
    
    }, "x-ibm-configuration": {
    "assembly": {
        "execute": [
            {
                "invoke": {
                    "target-url": "http://169.57.99.4:31985",
                    "verb": "keep",
                    "title": "invoke"
                }
            }
        ]
    },
    "cors": {
        "enabled": true
    }
    
    }, "basePath": "/poc-routeapi" }
  12. Agora, vamos executar os comandos para gerar o plano da infraestrutura e ter o resultado abaixo — ou seja, a infraestrutura criada.

      
    $ export IC_API_KEY={chave api-key}
    $ export IAAS_CLASSIC_USERNAME="{id user ibm cloud}"
    $ terraform plan
    $ terraform apply -auto-approve
      
    
    Utilize o comando $terraform init apenas a primeira vez, depois sempre que efetuar os ajustes, apenas execute o plano e o apply.
    Para remover toda a infra, execute $terraform destroy.

    O terraform tem o controle do ambiente a partir do arquivo terraform.tfstate.

  13. Na interface da IBM Cloud, a API ficará criada conforme abaixo:

    Definição da rota de integração, ou target endpoint, no API Gateway, na IBM Cloud

    Definição do CORS, no API Gateway, na IBM Cloud

    Os verbos declarados nos paths do documento apigw.json são demonstrados na interface conforme abaixo, e o botão ligado API Online é para que a API seja publicada com a url chamadora. Isso só foi feito por causa do parâmetro managed = var.managed, do documento 3-apigw.tf. Pois, se você não configurá-lo, a API não será publicada e terá que ser feita manualmente.

    Verbos criados a partir do swagger, do plano do Terraform, no API Gateway, na IBM Cloud.

    “Validação”: o momento mais esperado. Primeiro, nós testamos a chamada da API, através do endereço IP, exposto no serviço do kube (vide item 4.1). Esta API foi escrita em Python, como mencionado no item 3.1.

    Exemplo de chamada da API através do postman direto pelo IP e Porta pública do Kubernetes

    Por último, nós testamos a chamada da API, através da URL criada pelo API Gateway, no qual fará o target para o endereço IP, que configuramos no arquivo OpenAPI e que está apresentado no item 11. Como mencionado, é o mesmo endereço IP do kube.

    Exemplo de chamada da API, através do postman e da url criada no API Gateway, na IBM Cloud

Hands On – Parte 3

  1. Agora, vamos criar o recurso do template do Terraform, na Amazon Web Services API Gateway. A ideia é configurarmos um proxy que redirecione para o endpoint, criado no IKS (http://169.57.99.4:32226). Vou demonstrar, também, como configurar os recursos e os verbos REST API, a partir de uma especificação OpenAPI.

  2. Hands On – AWS API Gateway

    Novamente: em outra pasta, crie um arquivo de configuração do Terraform, especificando os recursos da AWS que você deseja provisionar. Salve este arquivo com a extensão .tf, exemplo: 1-serverless.tf. Este arquivo se faz obrigatório no momento que executarmos o />terraform init.

    
    terraform {
    required_providers {
     aws = {
       source  = "hashicorp/aws"
       version = "~> 3.0"
     }
    }
    }
    provider "aws" {
    region = var.region
    }
     
  3. Crie um arquivo com a declaração das variáveis para o uso de chaves, recursos e módulos que tenha necessidade em todo o seu projeto. Exemplo: 2-variables.tf. Notem que a variável region é utilizada no primeiro arquivo (1-serverless.tf). Foi criado na variável rest_api_path o valor do path, com o argumento de sistema {proxy+}, que tem a função na AWS de redirecionar o path sufixo para a integração.

    
    variable "region" {
    description = "Define what region the instance will be deployed"
    default     = "sa-east-1"
    }
    variable "rest_api_path" {
    default     = "/poc-routeapi/{proxy+}"
    description = "Path to create in the API gateway"
    type        = string
    }
    variable "rest_api_2_path" {
    default     = "/poc-routeapi-service"
    description = "Path to create in the API gateway the service backend"
    type        = string
    }
     
  4. Crie um arquivo com o nome 3-apigw.tf, que será utilizado para aplicar o plano de configuração do API Gateway. Em relação ao nome do service, mantenha routeFmsApi para que o provider entenda que estamos criando o API gateway na AWS.

    Repositório do serviço API Gateway na AWS Cloud

    Outro ponto interessante é o parâmetro body, que a partir da especificação OpenAPI, terá a seguinte implementação:

    • Em path, a api será criada a partir da definição do arquivo 2-variables.tf. O parâmetro, parameters, após o verbo (GET e POST), que, diferente da especificação OpenAPI na IBM Cloud, terá declaração de todos os queryparams da chamada. Caso não os declare, os queryparams não serão redirecionados ao target da integração. Neste momento, nós definimos apenas como requeridos. Os valores serão repassados no paragrafo seguinte.
    • Em x-amazon-apigateway-integration, nós definimos qual verbo será realizado, o target, a uri de destino, os parâmetros que serão repassados na integração, a função de ativar a API e criar a URL que será exposta. Para definir o CORS, nós implementamos o verbo OPTIONS e os response_parameters, conforme abaixo.

      
      resource "aws_api_gateway_rest_api" "routeFmsApi" {
      name = "routeFmsApi"
      body = jsonencode({
      openapi = "3.0.1"
      info = {
      title   = "API para demonstrar o acesso via proxy"
      version = "1.0"
      }
      paths = {
      (var.rest_api_path) = {
        get = {
          parameters = [
              {
                "in" = "path"
                "name" = "proxy"
                "required" = true
              },
              {
                "in" = "query"
                "name" = "priceList"
                "required" = true
              },
              {
                "in" = "query"
                "name" = "term"
                "required" = true
              },
              {
                "in" = "query"
                "name" = "page"
                "required" = true
              },
              {
                "in" = "query"
                "name" = "resultsPerPage"
                "required" = true
              }
          ]
          x-amazon-apigateway-integration = {
            httpMethod           = "GET"
            payloadFormatVersion = "1.0"
            type                 = "HTTP_PROXY"
            uri                  = "http://169.57.99.4:31985/{proxy}"
            requestParameters = {
              "integration.request.path.proxy" = "method.request.path.proxy"
              "integration.request.querystring.priceList": "method.request.querystring.priceList"
              "integration.request.querystring.term": "method.request.querystring.term"
              "integration.request.querystring.page": "method.request.querystring.page"
              "integration.request.querystring.resultsPerPage": "method.request.querystring.resultsPerPage"
            }
          }
        }
        post = {
          parameters = [{
            "in" = "path"
            "name" = "proxy"
            "required" = true
          }]
          x-amazon-apigateway-integration = {
            httpMethod           = "POST"
            payloadFormatVersion = "1.0"
            type                 = "HTTP_PROXY"
            uri                  = "http://169.57.99.4:31985/{proxy}"
            requestParameters = {
              "integration.request.path.proxy" = "method.request.path.proxy"
            }
          }
        }
        options = {
          responses = {
            200 = {
              description = "exemplo"
            }
          }
          x-amazon-apigateway-integration = {
            httpMethod = "OPTIONS"
            type       = "MOCK"
            responses = {
              200 = {
                statusCode = 200
                response_templates = {
                  "application/json" = ""
                }
                response_parameters = {
                  "method.response.header.Access-Control-Allow-Origin"  = "'*'",
                  "method.response.header.Access-Control-Allow-Headers" = "'*,origin, x-requested-with, accept, authorization, content-type'",
                  "method.response.header.Access-Control-Allow-Methods" = "'GET, PUT, POST, DELETE'",
                  "method.response.header.Access-Control-Max-Age"       = "'3628800'",
                  "method.response.header.Accept"                       = "'*/*'",
                  "method.response.header.Referrer-Policy"              = "'no-referrer-when-downgrade, no-referrer, strict-origin, origin, same-origin, origin-when-cross-origin, unsafe-url'"
                }
              }
            }
            requestTemplates = {
              "application/json" = ""
            }
          }
        }
      }
      (var.rest_api_2_path) = {
        get = {
          x-amazon-apigateway-integration = {
            httpMethod           = "GET"
            payloadFormatVersion = "1.0"
            type                 = "HTTP_PROXY"
            uri                  = "http://169.57.99.4:31985"
            requestParameters = {
              "integration.request.header.mpc-api-version" = "'v1'"
              "integration.request.header.token"           = "'89DB0D3A-53E7-41ED-8449-0D9AFD4A3D11'"
            }
          }
        }
      }
      }
      })
      endpoint_configuration {
      types = ["REGIONAL"]
      }
      }
      resource "aws_api_gateway_deployment" "routefmsapis" {
      rest_api_id = aws_api_gateway_rest_api.routeFmsApi.id
      triggers = {
      "redeployment" = sha1(jsonencode(
      aws_api_gateway_rest_api.routeFmsApi.body
      ))
      }
      lifecycle {
      create_before_destroy = true
      }
      }
      resource "aws_api_gateway_stage" "routefmsapis" {
      deployment_id = aws_api_gateway_deployment.routefmsapis.id
      rest_api_id   = aws_api_gateway_rest_api.routeFmsApi.id
      stage_name    = "dev"
      }
      
  5. API proxy configurada receberá o nome conforme o parâmetro path, que está definido em variable "rest_api_path" = "/poc-routeapi/{proxy+}". E será implementada conforme o recurso aws_api_gateway_deployment.

    API Proxy exposta e a url publicada após a execução do plano do Terraform no provider AWS Cloud

  6. O recurso “aws_api_gateway_stage” realiza o deploy da API, e você que define o ambiente.

    Procedimento para implantar a API na AWS Cloud através da interface

  7. Agora, vamos executar os comandos para gerar o plano da infraestrutura e ter o resultado abaixo — ou seja, a infraestrutura criada.

    
    $ terraform init
    $ terraform plan
    $ terraform apply -auto-approve
     
  8. Utilize o comando $terraform init somente a primeira vez, depois sempre que efetuar os ajustes, apenas execute o plano e o apply.

  9. Para remover toda a infra, execute $terraform destroy. O terraform tem o controle do ambiente, a partir do arquivo terraform.tfstate.

  10. “Validação”: o momento mais esperado. Nós testamos a chamada da API, através da url exposta na AWS API Gateway, configurada com o endereço IP, exposto no serviço do kube (vide item 4.1). Esta API foi escrita em Python, como mencionado no item 3.1.

    Exemplo de chamada da API através do postman e da url criada no API Gateway na AWS Cloud

  11. Para os dois casos, tanto do provedor IBM quanto AWS, temos um arquivo chamado 5-output.tf, que, após a execução do plano do terraform, nós podemos especificar a saída como URL, IP ou outros atributos que identificam a exposição do serviço com sucesso.

Fabrizio Rodrigues S. Sales

Referências:

As imagens foram extraídas do site da IBM Cloud.

Exposição de serviço kube:
https://cloud.ibm.com/docs/containers?topic=containers-cs_network_planning

CLI:
https://cloud.ibm.com/docs/solution-tutorials?topic=solution-tutorials-tutorials&locale=pt-BR

Terraform providers:
https://registry.terraform.io/browse/providers

OpenAPI:
https://swagger.io/specification/

Iks lab:
https://lionelmace.github.io/iks-lab/02-deploy-app.html

Schematics:
https://www.ibm.com/cloud/blog/automate-kubernetes-infrastructure-with-ibm-cloud-schematics?mhsrc=ibmsearch_a&mhq=IBM%20Cloud%20Schematics

Deprecated Building container images:
https://cloud.ibm.com/docs/ContinuousDelivery?topic=ContinuousDelivery-pipeline_container_images

Deprecated Building container images:
https://www.ibm.com/cloud/blog/announcements/ibm-cloud-container-registry-deprecating-container-builds

Buildkit:
https://earthly.dev/blog/what-is-buildkit-and-what-can-i-do-with-it/