Acesso de desenvolvedor ao EKS via IAM roles

TLDR: Substituir os tokens de ServiceAccount de longa duração por IAM roles por usuário + EKS Access Entries, dando a cada dev um único contexto kubectl com acesso apenas aos namespaces dos seus projetos.

Contexto

O setup anterior criava tokens de ServiceAccount de longa duração (kubernetes.io/service-account-token) guardados em ~/.config/wehive/. Esses tokens nunca expiram — token comprometido, ou de alguém que saiu, mantém acesso indefinidamente até intervenção manual. Pior: todos os devs compartilhavam o mesmo token por projeto, sem rastreabilidade individual.

O EKS oferece a alternativa nativa: IAM roles + Access Entries. Cada dev recebe um IAM role próprio, e o kubectl gera token de 15 minutos via aws eks get-token automaticamente. A revogação é imediata (remove o role → acesso acaba). Toda a granularidade fica no RBAC do Kubernetes (RoleBindings por namespace), dirigida pelo access.yml.

Problema secundário: rbac.tf e access.yml estavam duplicados — o terraform hardcodava um locals.projects espelhando o YAML, então projeto novo exigia atualizar em dois lugares. Esta spec elimina a duplicação gerando access.auto.tfvars.json a partir do access.yml.

Objetivos

  • Token de acesso expirando em 15 minutos (contra nunca, antes).
  • Revogação imediata: remover o IAM role tira o acesso na hora.
  • Um contexto único por dev (wehive-<alias>), vendo só os namespaces dos seus projetos.
  • access.yml como única fonte de verdade, sem duplicação no terraform.
  • Auditoria: o CloudTrail registra qual IAM role — logo, qual dev — fez cada operação.
  • Migração sem indisponibilidade: os tokens de SA continuam funcionando durante a transição.

Fora de escopo

  • Testes automatizados. Não há teste de terraform/shell neste repo; o ciclo é implementar → plan → apply → verificar comportamento real.
  • Remover os tokens de SA antigos no mesmo apply — eles convivem durante a transição.

Mudanças

infrastructure

Arquivo Ação
config/access.yml campo owners por projeto (já esperado por consumidores, estava vazio)
bin/helpers/gen-access-tfvars.sh novo — lê o access.yml com yq e gera access.auto.tfvars.json
src/modules/kubernetes/providers/aws/iam-developer-roles.tf novo — aws_iam_role + aws_iam_role_policy + aws_eks_access_entry por dev
src/modules/kubernetes/providers/aws/variables.tf management_account_id, developer_access, dev_projects
src/modules/kubernetes/variables.tf as três, com default
src/modules/kubernetes/_interface.tf repassa as três para module "aws"
src/modules/kubernetes/rbac.tf local.projects → var.dev_projects; RoleBindings por Group (aditivos)
src/shared/kubernetes/aws/terraform/main.tf repassa management_account_id ao módulo
.gitignore ignora access.auto.tfvars.json
CI step do gen-access-tfvars.sh antes do plan/apply
Makefile shared.kubernetes.plan/apply dependem de shared.kubernetes.tfvars

commons

Arquivo Ação
shell/tasks/infra/k8s/context/setup.sh cria o contexto único wehive-<alias> via --role-arn; auto-cria o profile wehive-dev-<alias> em ~/.aws/config
shell/tasks/infra/k8s/context/change.sh filtra contextos ^wehive- em vez de ^developer
shell/tasks/infra/k8s/context/summary.sh lista contextos wehive-*
skill commons:infra documentação de RBAC e setup de dev

Arquitetura

mermaid graph TD A["config/access.yml"] --> B["gen-access-tfvars.sh"] B --> C["access.auto.tfvars.json"] C --> D["terraform apply"] D --> E["aws_iam_role<br/>eks-dev-{alias}<br/>(um por dev, conta shared)"] D --> F["aws_eks_access_entry<br/>kubernetes_groups:<br/>developer-{proj}-member/owner"] D --> G["kubernetes_role_binding"] G --> H["Group member:<br/>admin em --staging<br/>readonly em --production"] G --> I["Group owner:<br/>admin em --staging<br/>full + exec em --production"]

  • Trust do IAM role: root da conta de management (arn:aws:iam::<mgmt>:root) — a mesma cadeia que o profile wehive-shared já usa. O dev não precisa de configuração AWS além do profile que o setup.sh cria.
  • Groups do Kubernetes: sem namespace-reader global — o dev só vê no k9s os namespaces onde tem RoleBinding explícito.

Contextos depois de make k8s.init: um wehive-<alias> por dev, mais devops para quem é owner de devops. Quem não tem projeto no access.yml não recebe contexto.

Como verificar

```bash # depois do terraform apply aws iam get-role –role-name eks-dev-porpino –profile wehive-shared aws eks describe-access-entry \ –cluster-name shared-kubernetes \ –principal-arn arn:aws:iam:::role/eks-dev-porpino \ --profile wehive-shared

depois de make k8s.init

kubectl config get-contexts kubectl config use-context wehive-porpino kubectl get namespaces # só os namespaces dos projetos do dev kubectl get pods -n gateway–staging # OK kubectl get pods -n gateway–production # OK (readonly) kubectl exec -it -n gateway--production -- sh # OK para owner, Forbidden para member

como outro dev, um projeto que ele não tem

kubectl config use-context wehive-matheus kubectl get pods -n gateway–staging # Forbidden ```

Documentação

  • Guia de acesso — modelo de grupo, acesso por namespace, contexto único por dev.
  • Skill commons:infra — seção de setup de dev: pré-requisitos (aws CLI com o profile wehive-shared, gh, yq), fluxo de renovação automática de token e o que acontece quando o access.yml muda.
  • Substitui o modelo de RBAC por projeto com SA tokens.