Como validar apps em relação às políticas da empresa em um pipeline de CI

Se sua organização usa o Anthos Config Management e o Policy Controller para gerenciar políticas em todos os clusters do Anthos, é possível validar a configuração de implantação de um app no pipeline de integração contínua (CI). Neste tutorial, mostramos como alcançar esse resultado. A validação do app é útil quando você é um desenvolvedor que cria um pipeline de CI para um app ou um engenheiro de plataforma que cria um modelo de pipeline de CI para várias equipes de aplicativos.

As políticas são uma parte importante da segurança e da conformidade de uma organização. O Policy Controller, que faz parte do Anthos Config Management, permite que sua organização gerencie essas políticas de maneira centralizada e declarativa para todos os clusters. Como desenvolvedor, você consegue aproveitar a natureza centralizada e declarativa dessas políticas. É possível usar essas características para validar seu app em relação a essas políticas o mais cedo possível no seu fluxo de trabalho de desenvolvimento. Aprender sobre violações de políticas no pipeline de CI em vez de fazer isso durante a implantação tem duas vantagens principais: permite que você faça um processo de shift left na segurança e diminua o feedback loop, reduzindo o tempo e o custo necessários para corrigir essas violações.

Se você for responsável pelo Anthos Config Management e pelo Policy Controller e quiser criar um pipeline de CI para eles (e não para um app específico), consulte Como usar o Policy Controller em um pipeline de CI.

Neste tutorial, o Cloud Build é usado como uma ferramenta de CI e um repositório do GitHub de amostra com políticas de demonstração.

Recursos

Neste tutorial, usamos várias ferramentas do Kubernetes. Esta seção explica quais são essas ferramentas, como elas interagem umas com as outras e se é possível substituí-las por outras.

As ferramentas usadas neste tutorial incluem o seguinte:

  • Policy Controller: é um produto do Google Cloud que faz parte do Anthos Config Management. Ele é baseado no projeto de código aberto Open Policy Agent - Gatekeeper. O Policy Controller aplica políticas sobre os objetos criados em um cluster do Kubernetes (por exemplo, impedindo o uso de uma opção específica ou aplicação do uso de um rótulo específico). Essas políticas são chamadas de restrições. As restrições são definidas como Recursos personalizados do Kubernetes. O Config Sync permite declarar essas restrições em um repositório Git e aplicar fluxos de trabalho de desenvolvimento tradicionais ao processo de gerenciamento de políticas. O Config Sync está disponível como um produto independente e como parte do Anthos Config Management. É possível usar o Open Policy Agent - Gatekeeper, em vez do Policy Controller para sua implementação.

  • GitHub: neste tutorial, usamos o GitHub para hospedar repositórios Git: um para um app de amostra e outro para o Anthos Config Management (que contém as restrições do Policy Controller). Para simplificar, os dois repositórios são duas pastas diferentes em um único repositório Git. Na realidade, seriam repositórios diferentes. É possível usar qualquer solução Git.

  • Cloud Build: o Cloud Build é a solução de CI do Google Cloud. Neste tutorial, nós o usaremos para executar os testes de validação. Os detalhes da implementação podem variar de um sistema de CI para outro, mas os conceitos descritos neste tutorial podem ser usados com qualquer sistema de CI baseado em contêiner.

  • Kustomize: o Kustomize é uma ferramenta de personalização nas configurações do Kubernetes. Isso é feito por meio de configurações de "base" e da aplicação de personalizações. Ele permite, uma abordagem "Não se repita" (DRY, na sigla em inglês) para configurações do Kubernetes. Com o Kustomize, você mantém elementos comuns a todos os seus ambientes nas configurações básicas e cria personalizações por ambiente. Neste tutorial, manteremos as configurações do Kustomize no repositório de apps à medida que "criamos" as configurações no pipeline de CI (por exemplo, aplicando personalizações). Use os conceitos descritos neste tutorial com qualquer ferramenta que produz configurações do Kubernetes e que estão prontas para serem aplicadas a um cluster. Por exemplo, o comando do helm template.

  • Kpt: o Kpt é uma ferramenta para criar fluxos de trabalho para configurações do Kubernetes. O Kpt permite buscar, exibir, personalizar, atualizar, validar e aplicar configurações do Kubernetes. Como ele funciona com arquivos Git e YAML, é compatível com a maioria das ferramentas atuais do ecossistema do Kubernetes. Neste tutorial, usamos o kpt no pipeline de CI para buscar as restrições do repositório do Anthos Config Management e validar as configurações do Kubernetes com base nessas restrições.

Pipeline

O pipeline de CI que usamos neste tutorial é mostrado no diagrama a seguir:

Pipeline de CI para o Policy Controller

O pipeline é executado no Cloud Build, e os comandos são executados em um diretório que contém uma cópia do repositório do app de amostra. O pipeline começa gerando as configurações finais do Kubernetes com o Kustomize. Depois, ele busca as restrições que queremos validar no repositório do Anthos Config Management usando o kpt. Por fim, o kpt é usado para validar as configurações do Kubernetes de acordo com essas restrições. Para realizar essa última etapa, usamos uma função de configuração específica chamada gatekeeper-validate, que realiza essa validação. Neste tutorial, você acionará o pipeline de CI manualmente. No entanto, na realidade, ele seria configurado para ser executado após um git push em seu repositório Git.

Objetivos

  • Executar um pipeline de CI para um aplicativo de amostra com o Cloud Build.
  • O pipeline falhou devido a uma violação da política.
  • Modificar o repositório do app de amostra para obedecer às políticas.
  • Executar o pipeline de CI novamente com êxito.

Custos

Neste tutorial, usamos o seguinte componente faturável do Google Cloud:

  • Cloud Build

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços.

Ao concluir o tutorial, exclua os recursos criados para evitar a continuidade do faturamento. Para mais detalhes, consulte a seção Como fazer a limpeza.

Antes de começar

  1. Selecione ou crie um projeto do Google Cloud. No Console do Google Cloud, acesse a página Gerenciar recursos.

    Acessar "Gerenciar recursos"

  2. Ative o faturamento do projeto.

  3. Para executar os comandos listados neste tutorial, abra o Cloud Shell e siga estas etapas:

    Acessar o Cloud Shell

  4. No Cloud Shell, execute gcloud config get-value project.

    Se o comando não retornar o ID do projeto que foi selecionado, configure o Cloud Shell para usar seu projeto.

    gcloud config set project PROJECT_ID
    

    Substitua PROJECT_ID pelo ID do projeto.

  5. No Cloud Shell, ative a API Cloud Build necessária:

    gcloud services enable cloudbuild.googleapis.com
    

Como validar as configurações do app de amostra

Nesta seção, você executará um pipeline de CI com o Cloud Build para um repositório de app de amostra que fornecemos. Esse pipeline valida a configuração do Kubernetes disponível nesse repositório de app de amostra em relação às restrições disponíveis em um repositório de amostra do Anthos Config Management.

Para validar as configurações do app, siga estas etapas:

  1. No Cloud Shell, clone o repositório do app de amostra.

    git clone https://github.com/GoogleCloudPlatform/anthos-config-management-samples.git
    
  2. Execute o pipeline de CI com o Cloud Build Os registros do build são exibidos diretamente no Cloud Shell.

    cd anthos-config-management-samples/ci-app/app-repo
    gcloud builds submit .
    

    O pipeline que você executa é definido no arquivo a seguir.

    steps:
    - id: 'Prepare config'
      # This step builds the final manifests for the app
      # using kustomize and the configuration files
      # available in the repository.
      name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
      entrypoint: '/bin/sh'
      args: ['-c', 'mkdir hydrated-manifests && kubectl kustomize config/prod > hydrated-manifests/prod.yaml']
    - id: 'Download policies'
      # This step fetches the policies from the Anthos Config Management repository
      # and consolidates every resource in a single file.
      name: 'gcr.io/kpt-dev/kpt'
      entrypoint: '/bin/sh'
      args: ['-c', 'kpt pkg get https://github.com/GoogleCloudPlatform/anthos-config-management-samples.git/ci-app/acm-repo/cluster@1.0.0 constraints
                      && kpt fn source constraints/ hydrated-manifests/ > hydrated-manifests/kpt-manifests.yaml']
    - id: 'Validate against policies'
      # This step validates that all resources comply with all policies.
      name: 'gcr.io/config-management-release/policy-controller-validate'
      args: ['--input', 'hydrated-manifests/kpt-manifests.yaml']

    No Policy Controller, as restrições são instâncias de modelos de restrição. Os modelos de restrição contêm o código Rego atual usado para implementar a restrição. A função gcr.io/kpt-fn/gatekeeper precisa do modelo de restrição e das definições de restrição para funcionar. O repositório de políticas de amostra contém ambos, mas, na realidade, eles podem ser armazenados em lugares diferentes. Use o comando kpt pkg get conforme necessário para fazer o download de modelos de restrição e restrições.

  3. Após alguns minutos, observe que o pipeline falha com o seguinte erro:

    [...]
    Step #2 - "Validate against policies": [RUNNING] "gcr.io/kpt-fn/gatekeeper:v0"
    Step #2 - "Validate against policies": [FAIL] "gcr.io/kpt-fn/gatekeeper:v0"
    Step #2 - "Validate against policies":   Results:
    Step #2 - "Validate against policies":     [ERROR] Deployment objects should have an 'owner' label indicating who created them. violatedConstraint: deployment-must-have-owner in object "apps/v1/Deployment/nginx-deployment" in file "prod.yaml"
    Step #2 - "Validate against policies":   Stderr:
    Step #2 - "Validate against policies":     "[error] apps/v1/Deployment/nginx-deployment : Deployment objects should have an 'owner' label indicating who created them."
    Step #2 - "Validate against policies":     "violatedConstraint: deployment-must-have-owner"
    Step #2 - "Validate against policies":     ""
    Step #2 - "Validate against policies":   Exit code: 1
    [...]
    

    A restrição que a configuração viola é definida no arquivo a seguir. É um recurso personalizado do Kubernetes chamado K8sRequiredLabels.

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: deployment-must-have-owner
    spec:
      match:
        kinds:
          - apiGroups: ["apps"]
            kinds: ["Deployment"]
      parameters:
        labels:
          - key: "owner"
        message: "Deployment objects should have an 'owner' label indicating who created them."

    Para o modelo de restrição correspondente a essa restrição, consulte requiredlabels.yaml no GitHub.

  4. Crie a configuração completa do Kubernetes e observe que o rótulo owner está realmente ausente. Para criar a configuração, faça o seguinte:

    kubectl kustomize config/prod
    

Como corrigir o app para estar em conformidade com as políticas da empresa

Nesta seção, você corrige a violação da política usando o Kustomize:

  1. No Cloud Shell, adicione uma seção commonLabels ao arquivo base do Kustomize:

    cat <<EOF >> config/base/kustomization.yaml
    commonLabels:
      owner: myself
    EOF
    
  2. Crie a configuração completa do Kubernetes e observe que o rótulo owner está presente:

    kubectl kustomize config/prod
    
  3. Execute novamente o pipeline de CI com o Cloud Build:

    gcloud builds submit .
    

    O pipeline agora é bem-sucedido com a seguinte saída:

    [...]
    Step #2 - "Validate against policies": [RUNNING] "gcr.io/kpt-fn/gatekeeper:v0"
    Step #2 - "Validate against policies": [PASS] "gcr.io/kpt-fn/gatekeeper:v0"
    [...]
    

Limpeza

  1. No Console do Cloud, acesse a página Gerenciar recursos:

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

A seguir