O blog da AWS

Configurando uma pipeline de CI/CD segura em uma Amazon Virtual Private Cloud sem acesso a internet

Por MJ Kubba. Traduzido ao Português por Ricardo Tasso.

Introdução

Com o surgimento da nuvem e o aumento da conscientização sobre segurança, o uso de Amazon VPCs sem acesso público a Internet também se expandiu rapidamente. Essa configuração é recomendada para garantir a segurança adequada por meio do isolamento. O requisito de isolamento também se aplica às pipelines de código, nos quais os desenvolvedores implementam seus módulos de aplicativos, pacotes de software e outras dependências, e pacotes em todo o ciclo de vida do desenvolvimento. Isso é feito sem a necessidade de enviar pacotes maiores do espaço do desenvolvedor para o espaço de teste ou para o ambiente de destino. Além disso, o AWS CodeArtifact é usado como um serviço de gerenciamento de artefatos que ajudará organizações de qualquer tamanho a armazenar, publicar e compartilhar com segurança pacotes de software usados em seu processo de desenvolvimento de software.

Percorreremos as etapas necessárias para criar uma pipeline segura e privada de integração contínua/desenvolvimento contínuo (CI/CD) sem acesso público a Internet e, ao mesmo tempo, manter a retenção de logs no Amazon CloudWatch. Utilizaremos o AWS CodeCommit como fonte, o CodeArtifact para os módulos e pacotes de software e o Amazon Simple Storage Service (Amazon S3) como armazenamento de artefatos.

Pré-requisitos

Os pré-requisitos para acompanhar esta postagem incluem:

  • Uma conta da AWS
  • Uma Virtual Private Cloud (Amazon VPC)
  • Uma pipeline de CI/CD — Pode ser CodePipeline, Jenkins ou qualquer ferramenta de CI/CD com a qual você queira integrar o CodeArtifact. Usaremos o CodePipeline em nosso passo a passo aqui.

Descrição da solução

O principal serviço em que nos concentraremos é o CodeArtifact, um serviço de repositório de artefatos totalmente gerenciado que facilita para organizações de qualquer tamanho armazenar, publicar e compartilhar com segurança pacotes de software usados em seu processo de desenvolvimento de software. O CodeArtifact funciona com gerenciadores de pacotes e ferramentas de criação comumente usados, como Maven e Gradle (Java), npm e yarn (JavaScript), pip e twine (Python) ou NuGet (.NET)

Arquitetura da pipeline CI/CD privada

Os usuários enviam o código para o CodeCommit, o CodePipeline detectará a alteração e iniciará o pipeline. No CodeBuild, o estágio de compilação utilizará os endpoints privados e baixará os pacotes de software necessários sem a necessidade de acessar a Internet.

O diagrama anterior mostra como as solicitações permanecem privadas na VPC e não passam pelo gateway da Internet, passando do CodeBuild pelo endpoint privado para o serviço CodeArtifact, tudo dentro da subnet privada.

As solicitações usarão os seguintes VPC endpoints para se conectar a esses serviços da AWS:

  • Endpoint do CloudWatch Logs (para que o CodeBuild coloque logs no CloudWatch)
  • Endpoints do CodeArtifact
  • Endpoint do AWS Security Token Service (AWS STS)
  • Endpoint do Amazon Simple Storage Service (Amazon S3)

Passo a passo

    1. Crie um repositório do CodeCommit:
        1. Navegue até o console do CodeCommit e clique em Criar repositório

          Figura 2. Captura de tela: botão Criar repositório.

        2. Digite o nome do repositório e clique em Criar

          Figura 3. Captura de tela: configuração do repositório com o nome mostrado como “Privado” e descrição vazia.

        3. Role para baixo e clique em Criar arquivo

          Figura 4. Botão Criar arquivo.

        4. Copie o arquivo buildspec.yml de exemplo e cole-o no editor

      Exemplo de arquivo buildspec.yml:

      version: 0.2
      phases:
        install:
          runtime-versions:
              nodejs: 16
          
      commands:
            - export AWS_STS_REGIONAL_ENDPOINTS=regional
            - ACCT=`aws sts get-caller-identity --region ${AWS_REGION} --query Account --output text`
            - aws codeartifact login --tool npm --repository Private --domain private --domain-owner ${ACCT}
            - npm install
        build:
          commands:
            - node index.js
      
        1. Nomeie o arquivo buildspec.yml, digite seu nome e endereço de e-mail e, em seguida, confirme as alterações.

          Figura 5. Captura de tela: Criar página de arquivo.

    2. Criar artefato de código
      1. Navegue até a console do CodeArtifact e clique em Criar repositório
      2. Dê um nome a ele e selecione npm-store como repositório upsteam público

        Figura 6. Captura de tela: Página para criar o repositório com o nome do repositório “Privado”.

      3. Para o domínio, selecione esta conta da AWS e insira um nome de domínio

        Figura 7. Captura de tela: Selecione a página do domínio.

      4. Clique em Avançar e depois em Criar repositório.

        Figura 8. Captura de tela: Página de revisão para criação do repositório.

    3. Crie uma pipeline CI/CD usando o CodePipeline
      1. Navegue até a console do CodePipeline e clique em Criar Pipeline.

        Figura 9. Captura de tela: botão Criar pipeline.

      2. Digite um nome, deixe a função de serviço como “Nova função de serviço” e clique em Avançar

        Figura 10. Captura de tela: escolha a configuração da pipeline com o nome da pipeline “Privado”.

      3. Selecione o AWS CodeCommit como seu provedor de origem
      4. Em seguida, escolha o repositório do CodeCommit que você criou anteriormente e, para a branch, selecione main e clique em Avançar.

        Figura 11. Captura de tela: Crie uma pipeline e adicione o estágio de origem.

      5. Para o estágio de compilação (build), escolha o AWS CodeBuild como provedor de compilação (build) e clique em Criar projeto

        Figura 12. Captura de tela: Crie o pipeline, adicione o estágio de compilação.

      6. Isso abrirá uma nova janela para criar o novo projeto. Dê um nome a este projeto

        Figura 13. Captura de tela: Janela de criação da etapa de compilação (build).

      7. Role para baixo até a seção Ambiente: selecione escolha Imagem gerenciada,
      8. Para Sistema operacional, selecione “Amazon Linux 2”,
      9. Tempo de execução (Runtime) “Padrão” e
      10. Para Imagem, selecione
        aws/codebuild/amazonlinux2-x86+64-standard:4.0
        Para a versão da imagem: Sempre use a imagem mais recente para esta versão de runtime
      11. Selecione Linux para o tipo de ambiente
      12. Deixe a opção Privilegiada desmarcada e defina Função de serviço como “Nova função de serviço”

        Figura 14. Captura de tela: Janela de configuração do ambiente da pipeline.

      13. Expanda Configurações adicionais e role para baixo até a seção VPC, selecione a VPC desejada, suas subnets (recomendamos selecionar várias AZs para garantir a alta disponibilidade) e o Grupo de Segurança (as regras do grupo de segurança devem permitir que os recursos que usarão o VPC endpoint para se comunicar com o serviço da AWS se comuniquem com a interface de rede do endpoint. O grupo de segurança VPC padrão será usado aqui como exemplo)

        Figura 15. Captura de tela: Janela de especificação da rede do projeto de compilação (build).

      14. Desça até o Buildspec e selecione “Usar um arquivo buildspec” e digite “buildspec.yml” para o nome Buildspec

        Figura 16. Captura de tela: Janela de criação do buildspec do projeto de compilação.

      15. Selecione a opção CloudWatch logs, você pode deixar o nome do grupo e o stream vazios, isso permitirá que o serviço use os valores padrões e clique em Continuar para o CodePipeline.

        Figura 17. Captura de tela: Janela de criação dos logs do projeto de compilação (build).

      16. Isso criará o novo projeto no CodeBuild, atualizará a página do CodePipeline, agora você pode clicar em Avançar

        Figura 18. Captura de tela: Janela de adição do estágio de compilação (build).

      17. Como não estamos implantando isso em nenhum ambiente, você pode pular o estágio de implantação e clicar em “Ignorar estágio de implantação”

        Figura 19. Captura de tela: Janela de criação do estágio de implantação na pipeline.

        Figura 20. Captura de tela: Pule a confirmação do estágio de implantação.

      18. Depois de receber o pop-up, clique em pular novamente, você verá a página de revisão, role até o fim e clique em Criar Pipeline.
    4. Crie um VPC endpoint para o Amazon CloudWatch Logs. Isso permitirá que o CodeBuild envie logs de execução para o CloudWatch
      1. Navegue até sua console de VPC e, no menu de navegação a esquerda, selecione “Endpoints”

        Figura 21. Captura de tela: VPC endpoint

      2. clique no botão Criar endpoint

        Figura 22. Captura de tela: Crie um endpoint.

      3. Para a categoria de serviço, selecione “Serviços da AWS”. Você pode definir um nome para o novo endpoint, recomenda-se usar algo descritivo.

        Figura 23. Captura de tela: Página de criação de endpoint.

      4. Na lista de serviços, pesquise o endpoint digitando logs na barra de pesquisa e selecionando aquele com com.amazonaws.us-west-2.logs.
        Esse passo a passo pode ser feito em qualquer região que ofereça suporte aos serviços. No exemplo aqui, irei usar us-west-2. Selecione a região apropriada para sua carga de trabalho.

        Figura 24. Captura de tela: crie serviços de seleção de endpoint com com.amazonaws.us-west-2.logs selecionado.

      5. Selecione a VPC a qual você deseja que o endpoint seja associado e verifique se a opção Ativar nome DNS está marcada em configurações adicionais.

        Figura 25. Captura de tela: a configuração de criar VPC do endpoint mostra a VPC selecionada.

      6. Selecione as subnets às quais você deseja que o endpoint seja associado, deixe o grupo de segurança como padrão e a política vazia.

        Figura 26. Captura de tela: seleção das subnets e grupos de segurança para criação do endpoint.

      7. Clique em Criar endpoint.

        Figura 27. Captura de tela: Botão de criação do endpoint.

    5. Crie um VPC endpoint para CodeArtifact. No momento em que escrevo este artigo, o CodeArtifact tinha dois endpoints: um para operações de API, como operações de nível de serviço e autenticação, e o outro para usar o serviço, como obter módulos para nosso código. Precisaremos dos dois endpoints para automatizar o trabalho com o CodeArtifact. Portanto, criaremos os dois endpoints com o DNS ativado.
      Além disso, precisaremos do endpoint do AWS Security Token Service (AWS STS) para a chamada da API get-caller-identity:Siga as etapas a-c das etapas que foram usadas na criação do endpoint de logs acima.

      1. Na lista de serviços, você pode pesquisar o endpoint digitando codeartifact na barra de pesquisa e selecionando aquele com com.amazonaws.us-west-2.codeartifact.api.

        Figura 28. Captura de tela: criação do endpoint selecionando o serviço com.amazonaws.us-west-2.codeartifact.api.

        Siga as etapas e-g da Parte 4.

        Em seguida, repita o mesmo para o serviço com.amazon.aws.us-west-2.codeartifact.repositories.

        Figura 29. Captura de tela: criação do endpoint selecionando o serviço com.amazonaws.us-west-2.codeartifact.api.

    6. Habilite um VPC endpoint para o AWS STS:Siga as etapas a-c da Parte 4
      1. Na lista de serviços, você pode pesquisar o endpoint digitando sts na barra de pesquisa e selecionando aquele com com.amazonaws.us-west-2.sts.

        Figura 30. Captura de tela: criação do endpoint selecionando o serviço com.amazon.aws.us-east-1.sts

        Em seguida, siga as etapas e-g da Parte 4.

    7. Crie um VPC endpoint para S3:Siga as etapas a-c da Parte 4
      1. Na lista de serviços, você pode pesquisar o endpoint digitando s3 na barra de pesquisa e selecionando aquele com com.amazonaws.us-west-2.s3, selecione aquele do tipo Gateway.Em seguida, selecione sua VPC e as tabelas de rotas para suas subnets. Isso atualizará automaticamente a tabela de rotas com o novo endpoint S3.

        Figura 31. Captura de tela: criação do endpoint selecionando o serviço com.amazonaws.us-west-2.s3 e seleção da VPC com as routing tables.

    8. Agora temos todos os endpoints definidos. A última etapa é atualizar sua pipeline para apontar para o repositório CodeArtifact ao extrair suas dependências de código. Vou usar o CodeBuild buildspec.yml como exemplo aqui.Certifique-se de que sua função AWS Identity and Access Management (IAM) do CodeBuild tenha as permissões para realizar ações de STS e CodeArtifact.Navegue até o console do IAM e clique em Funções no menu de navegação a esquerda e, em seguida, pesquise o nome da função do IAM, no nosso caso por termos selecionado a opção “Nova função de serviço” na etapa 2.k, criamos com o nome “codebuild-Private-service-role” (codebuild-<Nome do projeto de compilação>-service-role).

      Figura 32. Captura de tela: funções do IAM com a função CodeBuild-Private-Service-Role mostrada na pesquisa.

      No menu Adicionar permissões, clique em Criar política embutida.

      Procure por STS nos serviços e selecione STS.

      Figura 34. Captura de tela: editor visual do IAM com sts mostrados na pesquisa.

      Procure por “GetCallerIdentity” e selecione a ação.

      Figura 35. Captura de tela: editor visual do IAM com getCallerIdentity na pesquisa e na ação selecionada.

      Repita o mesmo com “GetServiceBearerToken”.

      Figura 36. Captura de tela: editor visual do IAM com GetServiceBearerToken na pesquisa e na ação selecionada.

      Clique em Revisar, adicione um nome e clique em Criar política.

      Figura 37. Captura de tela: página de revisão e botão Criar política.

      Você pode ver a nova política embutida adicionada a lista.

      Figura 38. Captura de tela: mostra a nova política embutida na lista.

      Para ações do CodeArtifact, faremos o mesmo nessa função, clique em Criar política embutida.

      Figura 39. Captura de tela: anexar políticas.

      Pesquise CodeArtifact nos serviços e selecione CodeArtifact.

      Figura 40. Captura de tela: selecione o serviço com o CodeArtifact na pesquisa.

      Pesquise “GetAuthorizationToken” nas ações e selecione essa ação na caixa de seleção.

      Figura 41. Captura de tela: o serviço CodeArtifact com a ação GetAuthorizationToken na pesquisa.

      Repita o procedimento para as ações “GetRepositoryEndpoint” e “ReadFromRepository”

      Clique em Recursos para corrigir os dois avisos e, em seguida, clique em Adicionar ARN no primeiro “Especificar ARN do recurso de domínio para a ação GetAuthorizationToken”.

      Figura 42. Captura de tela: com todas as ações selecionadas e 2 avisos.

      Você verá um pop-up com os campos Região, Conta e Nome do Domínio, insira sua região, o número da sua conta e o nome do domínio, que usamos com o nome “privado” quando criamos nosso domínio nos passos anteriores.

      Figura 43. Captura de tela: tela para adicionar o ARN.

      Em seguida, clique em Adicionar.

      Repita o mesmo processo para “Especificar o ARN do recurso do repositório para o ReadFromRepository e mais 1” e, desta vez, forneceremos Região, ID da conta, nome do domínio e nome do repositório. Usamos “Privado” para o repositório que criamos anteriormente e “privado” para o domínio.

      Figura 44. Captura de tela: tela para adicionar o ARN.

      Observe que é uma boa prática especificar o recurso de destino que estamos autorizando o acesso. Podemos usar a caixa de seleção “Qualquer”, mas queremos restringir o escopo de nossa função do IAM da melhor maneira possível.

    9. Navegue até o CodeCommit e clique no repositório que você criou anteriormente na etapa 1.

      Figura 45. Captura de tela: repositório no CodeCommit.

      Clique no menu Adicionar arquivo e, em seguida, no botão Criar arquivo.

      Cole o seguinte no espaço do editor:

      {
        "dependencies": {
          "mathjs": "^11.2.0"
        }
      }
      

      Nomeie o arquivo como “package.json”

      Adicione seu nome, e-mail e uma mensagem opcional para o commit.

      Repita esse processo para “index.js” e cole o seguinte no espaço do editor:

      const { sqrt } = require('mathjs')
      console.log(sqrt(49).toString())
      

      Figura 46. Captura de tela: tela de confirmação de alterações no CodeCommit.

      Isso forçará o pipeline a iniciar e começar a construir o aplicativo.

      Figura 47. Captura de tela: CodePipeline.

      Esse é um aplicativo muito simples que obtém a raiz quadrada de 49 e a registra na tela. Se você clicar no link Detalhes no estágio de compilação do pipeline, verá o resultado da execução do aplicativo NodeJS, os logs serão armazenados no CloudWatch e você poderá navegar até lá clicando no link Exibir o log inteiro “Mostrando as últimas xx linhas do log de compilação (build). Exibir o registro completo”.

      Figura 48. Captura de tela: mostrando as últimas 54 linhas do registro de compilação. Exibir o registro inteiro.

      Usamos um exemplo de npm no buildspec.yml acima. Para pip e twin podem ser usada configurações semelhantes,

      Para Maven, Gradle e NuGet, você deve definir variáveis de ambiente e alterar seu settings.xml e build.gradle, bem como instalar o plug-in para seu IDE. Para obter mais informações, consulte aqui.

Limpeza dos recursos criados

Navegue até o VPC endpoint a partir do console da AWS e exclua os endpoints que você criou.

Navegue até o CodePipeline e exclua o Pipeline que você criou.

Navegue até o CodeBuild e exclua o projeto de compilação criado.

Navegue até o CodeCommit e exclua o repositório que você criou.

Navegue até CodeArtifact e exclua o repositório e o domínio que você criou.

Navegue até o IAM e exclua as funções criadas:

Para o CodeBuild: codebuild-<Build Project Name>-service-role

Para o CodePipeline: AWSCodePipelineServiceRole-<Region>-<Project Name>

Conclusão

Neste post, implantamos uma pipeline completa de CI/CD com o CodePipeline orquestrando o CodeBuild para criar e testar um pequeno aplicativo NodeJS, usando o CodeArtifact para baixar as dependências do código do aplicativo. Tudo isso sem acessar a Internet pública e mantendo os logs no CloudWatch.

 

Este blog é uma tradução do conteúdo original em inglês (link aqui).

Sobre o Autor

MJ Kubba é arquiteto de soluções que gosta de trabalhar com clientes do setor público para criar soluções que atendam às necessidades de seus negócios. MJ tem mais de 15 anos de experiência projetando e implementando soluções de software. Ele tem uma grande paixão por DevOps e pela transformação cultural.

 

 

 

Tradutor

Ricardo Tasso é Arquiteto de Soluções para parceiros na AWS, atua ajudando na jornada de parceria com a AWS e a entregar a melhor solução aos clientes. Trabalha com Administração de Sistemas e Soluções de TI há mais de 15 anos, com experiência em redes, storage, Sistemas Operacionais, filas e messaging, com foco nos últimos 7 anos em DevOps, Serverless, Containers, Infra como Código, CI/CD, IA para DevOps, além de arquitetura e modernização de aplicações.

 

 

Revisor

Jonathan Cardoso é um Consultor DevOps Senior na AWS Professional Services atendendo clientes LATAM em diversos segmentos. Auxilia as empresas no processo de modernização de aplicações, transformação digital e cultural. Ensina cultura, práticas e ferramentas DevOps como mecanismo de aceleração do crescimento destas empresas.