Gerenciando repositórios no Github “como código” com Terraform — Parte 2

Bruna Pereira
5 min readApr 25, 2021

No artigo anterior entendemos as motivações e os primeiros passos para automatizar e gerenciar os repositórios do Github com código. Agora o que nos espera são algumas tarefas um pouco mais avançadas, bem como uma importante menção ao gerenciamento de estado. As novas funcionalidades que eu pretendo adicionar ao nosso projeto são:

  1. Adicionar um mecanismo de criação de repositórios
  2. Garantir os acessos aos repositórios em diferentes níveis de acordo com os grupos.

Na minha organização existem as seguintes regras:

  • Todas as engenheiras pertencem a um Time da organização, e tem acesso de leitura e escrita de Pull Requests
  • Todas as admins, além de terem permissões de leitura e escrita de PRs, têm o papel de mantainers nos times de Engineers e Admins.
  • Além disso, repositórios têm as seguintes características: são criados com um branch default, são todos privados, após o merge as branches são automaticamente deletadas, issues estão habilitados, entre outros.
  • Por fim, admins têm permissão de admin no grupo, enquanto engineers têm permissão de push.

Criando mais um grupo

Para estender a lógica que já criamos anteriormente, o primeiro que irei fazer é adicionar também um grupo de admins junto ao grupo de engineers.

Dica: Se você quiser, pode sempre rodar um terraform plan a cada mudança para verificar que está tudo indo como planejado.

Após criar os grupos, é hora de adicionar as pessoas!

Adicionando pessoas aos grupos

O primeiro que vou fazer é criar uma lista de usuários que são admins e engineers. Na definição do módulo, declaro as duas listas:

Pela primeira vez teremos variáveis dentro do módulo team então também crio um arquivo chamado variables.tf dentro da pasta team, com o seguinte conteúdo:

É hora de declarar o resource que faz a inserção dos usuários no time correspondente. O nome do resource é github_team_membership.

Ao final desta etapa, se você rodar terraform plan e terraform apply, já deveria ter os seus times corretamente populados com os usuários declarados no main.tf.

Dica: para adicionar pessoas a times, elas precisam estar na organização do projeto previamente. Se você rodar este comando e a pessoa não estiver no projeto, além de não aparecer no time, será enviado um convite a ela, que ficará aguardando no modo pendente.

Agora que temos times que contém usuários neles, vamos criar repositórios!

Criando repositórios

Seguindo o padrão da última funcionalidade, vou criar um módulo à parte para cada repositório que eu quiser criar. Para isso, vou definir o módulo dentro do main.tf na raiz e criar um diretório com o nome project, que também irá conter um arquivo main.tf.

Assim ficará a definição do módulo:

Para declarar o resource que faz a criação de repositórios, usamos o github_repository.

  • name: nome do repositório no Github.
  • description: a própria description que acompanha o repositório quando você acessa através da UI.
  • visibility: define se o repositório será privado ou público.

Perceba que name e description vêm de variáveis. Assim como fizemos anteriormente, vamos declarar as variáveis dentro do diretório do módulo, e defini-las dentro do módulo recém criado. Fica assim:

Já é possível rodar terraform plan e ver que o seu repositório já vai ser criado! O último passo é dar acessos baseados nos grupos e usuários criados anteriormente. Aproveite para rodar também o terraform apply como foi feito anteriormente, para aplicar todas as mudanças até aqui.

Concedendo acesso dos grupos de usuário no repositório criado

Por padrão, quando um repositório no Github é criado, a pessoa que criou fica com acesso de maintainer e dependendo da configuração da organização, ninguém mais tem acesso.

O que queremos atingir com esse passo é que toda vez que um repositório é criado, todo mundo do grupo de engineers tem acesso para fazer push e todo mundo do grupo de admins tem acesso de admin.

Pela primeira vez, teremos um resource que depende do resultado de um outro resource para ser aplicado. Quando criamos o grupo admins, a este grupo foi atribuído um id, e é este id que precisamos na hora de dizer que as pessoas do grupo de admins terá acesso de admin ao repositório.

O primeiro passo é expôr os ids dos grupos criados. Para isso, vamos criar dentro do diretórioteam os outputs.

Neste caso, engineers-team e admins-team são os nomes dos resources que eu dei quando criei o time. Lendo a documentação, eu concluí que dos 3 atributos exportados neste resource, o slug é suficiente para mim, então ele foi o único atributo que exportei.

O próximo passo é definir estes atributos como variável do meu módulo project. Adicione ao final do arquivo project/variables.tf as seguintes variáveis:

Dentro do módulo do repositório, declare as variáveis que conterão o nome dos times.

Dica: Repare a maneira como os valores exportados através do output são referenciados: module.[nome-do-modulo].[nome-da-variavel-definida-no-output].

Agora é só criar o resource que irá fazer a associação! O resource é o github_team_repository.

Agora está tudo pronto para rodar o terraform plan e terraform apply e tudo deveria funcionar como esperado!

O legal é que criando repositórios e concedendo acessos dessa maneira, não corre o risco de deixar ninguém de fora, e também não necessariamente quem cria o repositório tem acesso de admin a ele. Ao rodar este último comando, se a pessoa que está criando o repositório não é admin, ela "perde" sua permissão de admin para ter a permissão de push somente, o que é mais do que suficiente na grande maioria dos casos.

Gerenciamento de estados

Se você já trabalhou com Terraform antes, entende como funciona o gerenciamento de estados. Caso este tema seja novo para você, visite este artigo antes de colocar todo esse aprendizado que vimos aqui em produção. É muito importante entender como guardar o estado das alterações que fazemos num lugar centralizado e acessível.

Conclusão

Enquanto eu escrevia este artigo, eu escrevia o código junto. Neste repositório do Github você encontra o código completo. Se você chegou até aqui, espero que tenha se divertido tanto quanto eu 😄

Se ficou alguma dúvida ou se você tem alguma sugestão, escreve seu comentário aqui. Até a próxima!

--

--