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 maneira de gerenciar recursos. O Azure DevOps e a integração contínua e a automação de entrega contínua (CI/CD) podem ser um backdoor de segurança não intencional se não forem protegidos corretamente. Esses recursos devem ser protegidos espelhando o modelo RBAC (controle de acesso baseado em função) usado para o Gerenciador de Recursos.

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

Potenciais casos de utilização

Esta implementação de referência e demonstração é de código aberto e destina-se a ser usada como uma ferramenta de ensino para organizações que são novas no DevOps e precisam criar um modelo de governança para 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ócios da organização, que se refletem em qualquer implementação técnica de controles de acesso. Este modelo de exemplo usa uma empresa fictícia com o seguinte cenário comum (com 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 de negócios verticais, como "frutas" e "vegetais", que operam em grande parte de forma independente. Em cada domínio de negócios, há dois níveis ou privilégios, que são mapeados para grupos distintos *-admins ou *-devs Microsoft Entra. Isso permite que os desenvolvedores sejam direcionados ao configurar permissões na nuvem.

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

    • Produção. Apenas os 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 integração contínua (CI), mas também para implantação contínua (CD). Por exemplo, as implantações podem ser acionadas 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. Mas agora eles estão explorando opções para quebrar silos e incentivar a colaboração, criando os projetos de "colaboração" e "supermercado".

Este diagrama simplificado mostra como ramificações em um repositório Git mapeiam ambientes de desenvolvimento, preparação e produção:

Diagrama simplificado de ramificações do repositório Git mapeadas para vários ambientes web
Faça o download de um SVG deste diagrama.

Arquitetura

Este 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.

Visão geral da governança de ponta a ponta com o Microsoft Entra ID no centro
Faça o download de um SVG desta arquitetura.

Nota

Para tornar o conceito mais fácil de entender, o diagrama apenas ilustra o domínio "vegetais". O domínio "frutos" seria semelhante e usaria as mesmas convenções de nomenclatura.

Fluxo de Trabalho

A numeração reflete a ordem na qual os administradores de TI e arquitetos corporativos pensam 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 Gerenciador de Recursos. Os usuários não são adicionados individualmente. Em vez disso, a associação é atribuída pelos 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 nas etapas 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 este ambiente é limitado apenas a 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 do Microsoft Entra para um escopo específico. Por exemplo, os desenvolvedores têm a função de Colaborador no ambiente de produção.

    Microsoft Entra principal 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, esta implementação de referência atribui a Owner função às entidades de serviço. No entanto, na produção, você deve criar uma função personalizada que impeça uma entidade de serviço de remover quaisquer bloqueios de gerenciamento que você colocou em seus recursos. Isso ajuda a proteger os recursos contra danos acidentais, como a 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

    Os grupos de segurança funcionam como funções no Gestor de Recursos. Aproveite as funções internas e o padrão para Colaborador para desenvolvedores. Os administradores são atribuídos ao grupo de segurança Administrador de Projeto para permissões elevadas, permitindo que configurem permissões de segurança.

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

    • O Azure Resource Manager usa um modelo de permissões aditivas.
    • O Azure DevOps usa um modelo de permissões mínimas.

    Por esta razão, a pertença aos -admins grupos e -devs deve excluir-se mutuamente. Caso contrário, as pessoas afetadas teriam menos acesso do que o esperado no Azure DevOps.

    Group name Função de Gestor de Recursos Função Azure DevOps
    fruits-all
    fruits-devs Contribuinte Contribuinte
    fruits-admins Proprietário Administradores de projetos
    veggies-all
    veggies-devs Contribuinte Contribuinte
    veggies-admins Proprietário Administradores de projetos
    infra-all
    infra-devs Contribuinte Contribuinte
    infra-admins Proprietário Administradores de projetos

    Em um cenário de colaboração limitada, como a equipe de frutas convidando a equipe de vegetais para colaborar em um único repositório, eles usariam o veggies-all grupo.

    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. Ligaçõ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 principal do serviço e o segredo do cliente. Os administradores de projeto podem configurar o acesso a esse recurso protegido quando necessário, como quando exigem 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 apenas os pipelines em execução no contexto da production ramificação 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 filial, é fundamental configurar permissões para os repositórios Git e aplicar políticas de filial. Além de exigir que as compilações de CI sejam aprovadas, também exigimos que as solicitações pull tenham pelo menos dois aprovadores.

Componentes

Alternativas

O conceito de governança de ponta a ponta é independente do fornecedor. Embora este artigo se concentre no 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.

O 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 em modelos de governança global para CI/CD. O GitLab é outra plataforma baseada em Git que fornece recursos robustos de CI/CD.

Este cenário usa Terraform como sua infraestrutura como ferramenta de código (IaC). 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 cadeado vermelho indica as permissões de segurança que devem ser configuradas pelo usuário. Não configurar ou configurar incorretamente as permissões deixará suas cargas de trabalho vulneráveis.

Diagrama ilustrando um fluxo de trabalho de CI/CD de linha de base com o Azure DevOps
Faça o download de um SVG deste fluxo de trabalho.

Para proteger com êxito suas cargas de trabalho, 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 a pipelines e código. Eles geralmente são executados com identidades privilegiadas e destruirão suas cargas de trabalho se instruídos a fazê-lo. 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 acionam pipelines de automação.

Etapas de implantação Responsabilidade Description
Pedidos Pull User Os engenheiros devem revisar seu trabalho, incluindo o próprio código do Pipeline.
Proteção de ramos Compartilhada Configure o Azure DevOps para rejeitar alterações que não atendem a determinados padrões, como verificações de CI e revisões de pares (por meio de solicitações pull).
Pipeline como código User Um servidor de compilação excluirá todo o ambiente de produção se o código do pipeline o instruir a fazê-lo. Ajude a evitar isso usando uma combinação de solicitações pull e regras de proteção de ramificação, como aprovação humana.
Ligações de serviço Compartilhada Configure o Azure DevOps para restringir o acesso a essas credenciais.
Recursos do Azure Compartilhada Configure o RBAC no Gerenciador de Recursos.

Os seguintes conceitos e perguntas são importantes a considerar ao projetar um modelo de governança. Tenha em mente os casos de uso potenciais desta organização de exemplo.

1. Proteja seus ambientes com políticas de filiais

Como seu código-fonte define e aciona implantações, sua primeira linha de defesa é proteger seu repositório de gerenciamento de código-fonte (SCM). Na prática, isso é conseguido usando o fluxo de trabalho Pull Request em combinação com políticas de filial, 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 pela configuração da proteção de filiais. As verificações comuns de proteção de ramificação usadas para proteger suas implantações incluem:

  • Exigir que a compilação de CI seja aprovada. Útil para estabelecer a qualidade do código de linha de base, como revestimento 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 por pares Faça outra dupla verificação humana de que o código funciona como pretendido. Tenha cuidado extra quando forem feitas alterações no código do pipeline. Combine com compilações de CI para tornar as avaliações por pares menos entediantes.

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

Lembre-se que o Git é um sistema SCM distribuído. Um desenvolvedor pode se comprometer diretamente com sua filial local production . Mas quando o Git estiver configurado corretamente, esse push será automaticamente rejeitado 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 do fornecedor. Os recursos de solicitação pull e proteção de ramificação estão disponíveis em vários provedores de SCM, incluindo Azure Repos, GitHub e GitLab.

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

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

No Azure, uma entidade de segurança pode ser uma entidade de usuário ou uma entidade sem cabeça, como uma entidade de serviço ou identidade gerenciada. Em todos os ambientes, as entidades de segurança devem seguir o princípio do menor privilégio. Embora as entidades de segurança possam ter acesso expandido em ambientes de pré-produção, os ambientes 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 RBAC do Azure para entidades de usuário para alinhá-las com essas entidades de menor privilégio.

Também é importante modelar o Azure RBAC distintamente do Azure DevOps RBAC. O objetivo do pipeline é minimizar o acesso direto ao Azure. Exceto em casos especiais como inovação, aprendizagem e resolução de problemas, a maioria das interações com o Azure deve ser conduzida por meio de pipelines fechados e criados para fins específicos.

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

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

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

Mas um CI/CD Build Agent excluirá todo o seu ambiente de produção se for instruído a fazê-lo. Para evitar alterações destrutivas irreversíveis, criamos uma função personalizada que:

  • Remove as políticas de acesso ao Cofre da Chave
  • Remove bloqueios de gerenciamento que, por design, devem impedir que os recursos sejam excluídos (um requisito comum em setores regulamentados)

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

{
  "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 seus propósitos, 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.

Implementar este cenário

Esse cenário vai além do Gerenciador de Recursos. É por isso que usamos o Terraform, que nos permite também criar entidades 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 GitHub Governance on Azure Demo - from DevOps to ARM.

Preços

Os custos do Azure DevOps dependem do número de usuários em sua organização que exigem acesso, juntamente com outros fatores, como o número de compilações/lançamentos simultâneos necessários e o número de usuários. Azure Repos e Azure Pipelines são recursos do serviço Azure DevOps. Para obter mais informações, consulte Preços do 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 destes níveis são calculados por utilizador. Para obter mais informações, veja Preços do Microsoft Entra.

Contribuidores

Este artigo é mantido pela Microsoft. Foi originalmente escrito pelos seguintes contribuidores.

Autor principal:

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

Próximos passos