Governança de ponta a ponta no Azure ao usar CI/CD

Microsoft Entra ID
Azure DevOps
Azure Pipelines
Azure Resource Manager

Ao desenvolver um modelo de governança para sua organização, é importante lembrar que o Azure Resource Manager é apenas uma das maneiras de gerenciar recursos. A automação do Azure DevOps e integração contínua e entrega contínua (CI/CD) pode ser um back-door de segurança não intencional se não estiver devidamente protegida. Esses recursos devem ser protegidos pelo espelhamento do modelo RBAC (controle de acesso baseado em função) usado para o Resource Manager.

O conceito de governança de ponta a ponta é independente de fornecedor. A implementação descrita aqui usa Azure DevOps, mas as alternativas também são mencionadas brevemente.

Possíveis casos de uso

Essa implementação e demonstração de referência são de código aberto e devem ser usadas como uma ferramenta de ensino para organizações que são novas para DevOps e precisam criar um modelo de governança para a implantação no Azure. Leia este cenário cuidadosamente para entender as decisões por trás do modelo usado neste repositório de exemplo.

Qualquer modelo de governança deve estar vinculado às regras de negócio da organização, que se refletem em qualquer implementação técnica dos controles de acesso. Esse modelo de exemplo usa uma empresa fictícia com o seguinte cenário comum (com os requisitos de negócios):

  • Grupos do Microsoft Entra que se alinham com domínios de negócios e modelos de permissões
    A organização tem muitos domínios comerciais verticais, como "frutas" e "vegetais", que operam de maneira amplamente independente. Em cada domínio de negócios, há dois níveis ou privilégios que são mapeados para grupos *-admins ou *-devs distintos do Microsoft Entra. Isso permite que os desenvolvedores sejam direcionados ao configurar permissões na nuvem.

  • Ambientes de implantação
    Cada equipe tem dois ambientes:

    • Produção. Somente administradores têm privilégios elevados.
    • Não produção. Todos os desenvolvedores têm privilégios elevados (para incentivar a experimentação e a inovação).
  • Metas de automação
    Cada aplicativo deve implementar o Azure DevOps não apenas para CI (integração contínua), mas também para a CD (implantação contínua). Por exemplo, as implantações podem ser disparadas automaticamente por alterações no repositório Git.

  • Jornada na nuvem até agora
    A organização começou com um modelo de projeto isolado para acelerar a jornada para a nuvem. No entanto, agora eles estão explorando opções para quebrar os silos e incentivar a colaboração criando os projetos "colaboração" e "supermercado".

Este diagrama simplificado mostra como as ramificações em um repositório Git são mapeadas para ambientes de desenvolvimento, preparo e produção:

Simplified diagram of Git repository branches mapped to various web environments
Baixe um SVG deste diagrama.

Arquitetura

Esse diagrama mostra como a vinculação do Resource Manager e do CI/CD ao Microsoft Entra ID é a chave para ter um modelo de governança de ponta a ponta.

End-to-end governance overview with Microsoft Entra ID at the center
Baixe um SVG dessa arquitetura.

Observação

Para facilitar a compreensão do conceito, o diagrama ilustra apenas o domínio "vegetais". O domínio "frutas" seria semelhante e usaria as mesmas convenções de nomenclatura.

Workflow

A numeração reflete a ordem em que os administradores de TI e os arquitetos a empresa consideram e configuram seus recursos de nuvem.

  1. Microsoft Entra ID

    Integramos o Azure DevOps com o Microsoft Entra ID para ter um único plano de identidade. Isso significa que um desenvolvedor usa a mesma conta do Microsoft Entra para o Azure DevOps e o Resource Manager. Os usuários não são adicionados individualmente. Em vez disso, a associação é atribuída por grupos do Microsoft Entra para que possamos remover o acesso de um desenvolvedor aos recursos em uma única etapa, removendo suas associações de grupo do Microsoft Entra. Para cada domínio, criamos:

    • Grupos do Microsoft Entra. Dois grupos por domínio (descritos mais detalhadamente na etapa 4 e 5 mais adiante neste artigo).
    • Entidades de serviço. Uma entidade de serviço explícita por ambiente.
  2. Ambiente de produção

    Para simplificar a implantação, essa implementação de referência usa um grupo de recursos para representar o ambiente de produção. Na prática, você deve usar uma assinatura diferente.

    O acesso privilegiado a esse ambiente é limitado apenas aos administradores.

  3. Ambiente de desenvolvimento

    Para simplificar a implantação, essa implementação de referência usa um grupo de recursos para representar o ambiente de desenvolvimento. Na prática, você deve usar uma assinatura diferente.

  4. Atribuições de função no Resource Manager

    Embora nossos nomes de grupo do Microsoft Entra impliquem uma função, os controles de acesso não são aplicados até que uma atribuição de função seja configurada. Isso atribui uma função a uma entidade de segurança do Microsoft Entra para um escopo específico. Por exemplo, os desenvolvedores têm a função de colaborador no ambiente de produção.

    Entidade de segurança do Microsoft Entra Ambiente de desenvolvimento (Resource Manager) Ambiente de produção (Resource Manager)
    veggies-devs-group Proprietário Leitor
    veggies-admins-group Proprietário Proprietário
    veggies-ci-dev-sp Função personalizada *
    veggies-ci-prod-sp Função personalizada *

    * Para simplificar a implantação, essa implementação de referência atribui a função Owner às entidades de serviço. No entanto, na produção, você deve criar uma função personalizada que impeça que uma entidade de serviço remova bloqueios de gerenciamento que você colocou em seus recursos. Isso ajuda a proteger os recursos contra danos acidentais, como exclusão de banco de dados.

    Para entender o raciocínio por trás das atribuições de função individuais, consulte a seção de considerações mais adiante neste artigo.

  5. Atribuições de grupo de segurança no Azure DevOps

    Grupos de segurança funcionam como funções no Resource Manager. Aproveite as funções internas e o padrão de colaborador para os desenvolvedores. Os administradores são atribuídos ao grupo de segurança administrador de projeto para permissões elevadas, permitindo que eles configurem permissões de segurança.

    Observe que o Azure DevOps e o Resource Manager têm modelos de permissões diferentes:

    Por esse motivo, a associação aos grupos -admins e -devs deve ser mutuamente exclusiva. Caso contrário, as pessoas afetadas terão menos acesso do que o esperado no Azure DevOps.

    Nome do grupo Função do Resource Manager Função do Azure DevOps
    fruits-all
    fruits-devs Colaborador Colaborador
    fruits-admins Proprietário Administradores do Projeto
    veggies-all
    veggies-devs Colaborador Colaborador
    veggies-admins Proprietário Administradores do Projeto
    infra-all
    infra-devs Colaborador Colaborador
    infra-admins Proprietário Administradores do Projeto

    Em um cenário de colaboração limitada - por exemplo, a equipe “frutas” convida a equipe “verduras” a colaborar em um único repositório - eles usariam o grupo veggies-all.

    Para entender o raciocínio por trás das atribuições de função individuais, consulte a seção de considerações mais adiante neste artigo.

  6. Conexões de serviço

    No Azure DevOps, uma conexão de serviço é um wrapper genérico em torno de uma credencial. Criamos uma conexão de serviço que contém o ID do cliente da entidade de serviço e o segredo do cliente. Os administradores de projeto podem configurar o acesso a esse recurso protegido quando necessário, por exemplo, ao exigir aprovação humana antes da implantação. Essa arquitetura de referência tem duas proteções mínimas na conexão de serviço:

    • Os administradores devem configurar permissões de pipeline para controlar quais pipelines podem acessar as credenciais.
    • Os administradores também devem configurar uma verificação de controle de ramificação para que somente os pipelines em execução no contexto da ramificação production possam usar o prod-connection.
  7. Repositórios Git

    Como nossas conexões de serviço estão vinculadas a ramificações por meio de controles de ramificação, é essencial configurar permissões para os repositórios Git e aplicar políticas de ramificação. Além de exigir que os builds de CI sejam aprovados, também exigimos que as solicitações de pull tenham pelo menos dois aprovadores.

Componentes

Alternativas

O conceito de governança de ponta a ponta é independente de fornecedor. Embora este artigo se concentre Azure DevOps, o Azure DevOps Server pode ser usado como um substituto local. Como alternativa, você também pode usar um conjunto de tecnologias para um pipeline de desenvolvimento de CI/CD de código aberto usando opções como Jenkins e GitLab.

Os Azure Repos e o GitHub são plataformas criadas para usar o sistema de controle de versão do Git de código aberto. Embora seus conjuntos de recursos sejam um pouco diferentes, ambos podem ser integrados a modelos de governança global para CI/CD. O GitLab é outra plataforma baseada em Git que fornece recursos avançados de CI/CD.

Esse cenário usa o Terraform como sua ferramenta IaC (infraestrutura como código). As alternativas incluem Jenkins, Ansible e Chef.

Considerações

Para obter governança de ponta a ponta no Azure, é importante entender o perfil de segurança e permissões do caminho do computador do desenvolvedor para a produção. O diagrama a seguir ilustra um fluxo de trabalho de CI/CD de linha de base com o Azure DevOps. O ícone de bloqueio vermelho indica permissões de segurança que devem ser configuradas pelo usuário. Não configurar ou configurar permissões incorretamente deixará suas cargas de trabalho vulneráveis.

Diagram illustrating a baseline CI/CD workflow with Azure DevOps
Baixe um SVG deste fluxo de trabalho.

Para proteger suas cargas de trabalho com êxito, você deve usar uma combinação de configurações de permissão de segurança e verificações humanas em seu fluxo de trabalho. É importante que qualquer modelo RBAC também se estenda para pipelines e código. Eles geralmente são executados com identidades privilegiadas e destruirão suas cargas de trabalho se instruídos a fazer isso. Para evitar que isso aconteça, você deve configurar políticas de ramificação em seu repositório para exigir aprovação humana antes de aceitar alterações que disparam pipelines de automação.

Estágios de implantação Responsabilidade Descrição
Solicitações pull Usuário Os engenheiros devem fazer revisão em pares de seu trabalho, incluindo o próprio código de pipeline.
Proteção de branch Compartilhado Configure o Azure DevOps para rejeitar alterações que não atendem a determinados padrões, como verificações de CI e revisões em pares (por meio de solicitações de pull).
Pipeline como código Usuário Um servidor de build excluirá todo o ambiente de produção se o código do pipeline o instruir a fazer isso. Ajude a evitar isso usando uma combinação de solicitações de pull e regras de proteção de ramificação, como aprovação humana.
Conexões de serviço Compartilhado Configure o Azure DevOps para restringir o acesso a essas credenciais.
Recursos do Azure Compartilhado Configure o RBAC no Resource Manager.

Os conceitos e perguntas a seguir são importantes ao criar um modelo de governança. Tenha em mente os possíveis casos de uso desta organização de exemplo.

1. Proteger seus ambientes com políticas de ramificação

Como o código-fonte define e dispara implantações, sua primeira linha de defesa é proteger o repositório SCM (gerenciamento de código-fonte). Na prática, isso é feito usando o fluxo de trabalho solicitação de pull em combinação com políticas de ramificação, que definem verificações e requisitos antes que o código possa ser aceito.

Ao planejar seu modelo de governança de ponta a ponta, os usuários privilegiados (veggies-admins) serão responsáveis por configurar a proteção de ramificação. As verificações comuns de proteção de ramificação usadas para proteger suas implantações incluem:

  • Exigir que o build de CI seja aprovado. Útil para estabelecer a qualidade do código de linha de base, como lint de código, testes de unidade e até mesmo verificações de segurança, como verificações de vírus e credenciais.

  • Exigir revisão em pares Fazer com que outro humano verifique se o código funciona conforme o esperado. Tenha cuidado extra quando alterações forem feitas no código do pipeline. Combine com builds de CI para tornar as revisões em pares menos entediantes.

O que acontece se um desenvolvedor tentar fazer push diretamente para a produção?

Lembre-se de que o Git é um sistema SCM distribuído. Um desenvolvedor pode se comprometer diretamente com seu branch production local. No entanto, quando o Git estiver configurado corretamente, esse push será rejeitado automaticamente pelo servidor Git. Por exemplo:

remote: Resolving deltas: 100% (3/3), completed with 3 local objects.
remote: error: GH006: Protected branch update failed for refs/heads/main.
remote: error: Required status check "continuous-integration" is expected.
To https://github.com/Azure/devops-governance
 ! [remote rejected] main -> main (protected branch hook declined)
error: failed to push some refs to 'https://github.com/Azure/devops-governance'

Observe que o fluxo de trabalho no exemplo é independente de fornecedor. Os recursos de solicitação de pull e proteção de ramificação estão disponíveis em vários provedores SCM, incluindo Azure Repos, GitHub e GitLab.

Depois que o código tiver sido aceito em uma ramificação protegida, a próxima camada de controles de acesso será aplicada pelo servidor de build (como Azure Pipelines).

2. De que acesso as entidades de segurança precisam?

No Azure, uma entidade de segurança pode ser uma entidade de usuário ou uma entidade headless, como uma entidade de serviço ou uma identidade gerenciada. Em todos os ambientes, as entidades de segurança devem seguir a entidade de segurança com privilégios mínimos. Embora as entidades de segurança possam ter expandido o acesso em ambientes de pré-produção, os ambientes do Azure de produção devem minimizar as permissões permanentes, favorecendo o acesso just-in-time (JIT) e o Acesso Condicional do Microsoft Entra. Crie suas atribuições de função do RBAC do Azure para entidades de usuário alinharem-se a essas entidades de privilégios mínimos.

Também é importante modelar o RBAC do Azure distintamente do RBAC do Azure DevOps. A finalidade do pipeline é minimizar o acesso direto ao Azure. Com exceção de casos especiais, como inovação, aprendizado e resolução de problemas, a maioria das interações com o Azure deve ser realizada por meio de pipelines de finalidade específica e restritos.

Para entidades de serviço do Pipeline do Azure, considere usar uma função personalizada que a impeça de remover bloqueios de recursos e executar outras ações destrutivas fora do escopo para sua finalidade.

3. Criar uma função personalizada para a entidade de serviço usada para acessar a produção

É um erro comum dar aos agentes de build de CI/CD funções e permissões de proprietário. As permissões de colaborador não serão suficientes se o pipeline também precisar executar atribuições de função de identidade ou outras operações privilegiadas, como gerenciamento de política do Key Vault.

No entanto, um agente de build de CI/CD excluirá todo o ambiente de produção se for informado para fazer isso. Para evitar alterações destrutivas irreversíveis, criamos uma função personalizada que:

  • Remove as políticas de acesso ao Key Vault
  • Remove bloqueios de gerenciamento que, por padrão, devem impedir a exclusão de recursos (um requisito comum em setores regulamentados)

Para fazer isso, criamos uma função personalizada e removemos as ações Microsoft.Authorization/*/Delete.

{
  "Name": "Headless Owner",
  "Description": "Can manage infrastructure.",
  "actions": [
    "*"
  ],
  "notActions": [
    "Microsoft.Authorization/*/Delete"
  ],
  "AssignableScopes": [
    "/subscriptions/{subscriptionId1}",
    "/subscriptions/{subscriptionId2}",
    "/providers/Microsoft.Management/managementGroups/{groupId1}"
  ]
}

Se isso remover muitas permissões para suas finalidades, consulte a lista completa na documentação oficial para operações do provedor de recursos do Azure e ajuste sua definição de função conforme necessário.

Implantar este cenário

Esse cenário se estende além do Resource Manager. É por isso que usamos o Terraform, que nos permite também criar entidades de segurança no Microsoft Entra ID e inicializar o Azure DevOps usando uma única infraestrutura como ferramenta de código.

Para obter o código-fonte e instruções detalhadas, visite o repositório do GitHub Governança na demonstração do Azure – do DevOps ao ARM.

Preços

Os custos do Azure DevOps dependem do número de usuários em sua organização que precisam de acesso, juntamente com outros fatores, como o número de builds/versões simultâneos necessários e o números de usuários. O Azure Repos e o Azure Pipelines são recursos do serviço do Azure DevOps. Para saber mais, confira Preços de Azure DevOps.

No Microsoft Entra ID, o tipo de gerenciamento de acesso de grupo necessário para esse cenário é fornecido nas edições Premium P1 e Premium P2. Os preços para essas camadas são calculados por usuário. Para obter mais informações, confira Preços do Microsoft Entra.

Colaboradores

Esse artigo é mantido pela Microsoft. Ele foi originalmente escrito pelos colaboradores a seguir.

Autor principal:

  • Julie Ng | Engenheiro de Serviços Sênior

Próximas etapas