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.ymlcomo ú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 profilewehive-sharedjá usa. O dev não precisa de configuração AWS além do profile que osetup.shcria. - Groups do Kubernetes: sem
namespace-readerglobal — 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::
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
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 (awsCLI com o profilewehive-shared,gh,yq), fluxo de renovação automática de token e o que acontece quando oaccess.ymlmuda. - Substitui o modelo de RBAC por projeto com SA tokens.