GCP para engenheiros AWS: como seus instintos AWS se traduzem (e onde falham)
Você já sabe como organizar contas, conceder permissões e inicializar o estado na AWS. Veja como fazer as mesmas coisas no Google Cloud - os conceitos que se mapeiam diretamente e os quatro pontos onde sua memória muscular da AWS irá ativamente te enganar.
Se você é fluente em AWS e agora está olhando para o Google Cloud, a boa notícia é que ~80% dos seus instintos se transferem diretamente: há uma hierarquia para organizar as coisas, uma forma baseada em funções para conceder acesso, uma abordagem OIDC para CI sem chaves e uma dança de inicialização para "cold-start your state backend". A má notícia são os outros 20% - e eles estão concentrados em alguns pontos de alto tráfego onde fazer a coisa da AWS produz uma negação confusa em vez de um erro óbvio. Esta postagem é a camada de tradução: os mesmos trabalhos que você faz na AWS, feitos no GCP, com as armadilhas destacadas.
A versão curta, se você ler apenas um parágrafo: A hierarquia do GCP (organization -> folder -> project -> resource) se mapeia diretamente para AWS Organizations -> OU -> account -> resource, mas três coisas quebram sua memória muscular. IAM é uma política de permissão apenas, vinculada à árvore de recursos e herdada para baixo - não há política anexada a um usuário. As APIs de serviço de um project começam todas desativadas, e nada funciona até que você habilite cada uma delas. E você não assume roles, você personifica service accounts, que são elas próprias recursos com sua própria política de acesso. Tudo abaixo expande esses pontos.
A maior mudança: permissões vivem na árvore, não em identidades
Na AWS, o modelo mental é "anexar uma política a uma identidade". Você cria um user ou um role, anexa um JSON a ele, e a permissão viaja com o principal. Políticas de recurso existem, mas a política anexada à identidade é o centro de gravidade.
O GCP inverte isso. Uma política IAM é um conjunto de bindings - pares (member, role) - anexados a um nó na hierarquia de recursos (organization, folder, project, ou um recurso individual). A política reside na coisa que está sendo acessada, não na identidade que está acessando. Seu acesso efetivo em qualquer ponto é a união de cada binding herdado da raiz até aquele nó. Conceda roles/compute.admin a um grupo no nível da folder e cada project sob essa folder o herda.
Se você já usou Azure RBAC, isso parecerá familiar - é role-at-a-scope com herança descendente. A regra que o salva:
Quando o GCP nega algo, pare de procurar por "a política no user". Procure pelo binding na org, folder, project ou resource - e lembre-se que ele herda para baixo, então a concessão que importa pode estar três níveis acima.
Alguns detalhes que diferem da AWS:
- Roles vêm em três categorias. Roles Primitive (
roles/owner,roles/editor,roles/viewer) são o trio legado mais amplo - evite-os em ambientes reais. Roles Predefined são os roles por serviço mais granulares que você deve realmente usar (roles/storage.objectViewer,roles/compute.instanceAdmin.v1, ...). Roles Custom são seus para criar quando o conjunto predefinido é muito amplo. - O modelo base é aditivo e permite apenas. Não há
Effect: Denypor declaração embutido em cada política da mesma forma que na AWS. O acesso efetivo é apenas a união de permissões. - Deny é uma camada separada. Quando você precisa de um "nunca, independentemente das concessões", você escreve uma IAM deny policy - um objeto distinto anexado à org/folder/project que é avaliado antes das permissões. É o mais próximo de uma declaração
Denyinline, mas é deliberadamente fora de banda. - Guardrails são uma terceira coisa novamente: o Organization Policy Service. Constraints como
constraints/compute.vmExternalIpAccessouconstraints/iam.disableServiceAccountKeyCreationsão o análogo do GCP para SCPs. Eles se anexam na org/folder/project, herdam para baixo e restringem o que pode existir ou ser configurado em vez de quem pode chamar o quê. Pense em "guardrail em forma de SCP", não em "IAM role".
Então, onde a AWS oferece uma gramática de permitir/negar dentro do IAM, o GCP distribui o trabalho entre allow bindings, deny policies e org-policy constraints. Mesmos resultados, três mecanismos.
Tudo é um project - e suas APIs começam desativadas
O project é a unidade fundamental do GCP. É o análogo aproximado de uma AWS account: um limite de isolamento, um escopo IAM e um alvo de faturamento, tudo ao mesmo tempo. Mas um project é muito mais leve que uma account - barato para criar, fácil de excluir, feito para ser criado às dezenas. O padrão idiomático é um project por workload por ambiente (app-qa, app-prod), não um punhado de accounts compartilhadas divididas por tags.
Três coisas sobre projects não têm um equivalente limpo na AWS:
- Um project tem três identificadores, e as diferenças são importantes. O project ID é uma string globalmente única, escolhida por humanos e imutável (
acme-app-prod-7f3a) - é o que você coloca em quase todos os comandos e caminhos de recurso. O project number é um número inteiro globalmente único que o GCP atribui. O display name é mutável e cosmético. Escolha o ID com cuidado; você nunca poderá alterá-lo. - As Service APIs estão desativadas por padrão. Este é o tropeço mais comum no primeiro dia. Antes de criar uma VM, você habilita
compute.googleapis.com; antes de um bucket,storage.googleapis.com; e assim por diante, por project. Sua primeira "negação" no GCP geralmente não é uma IAM role ausente - éAPI [compute.googleapis.com] not enabled on project. Na AWS, os serviços simplesmente existem; no GCP, cada project é uma tela em branco e você ativa exatamente a superfície que pretende usar. (No Terraform, isso égoogle_project_service; na CLI,gcloud services enable.) - Projects são o limite natural de blast-radius e quota. Quotas, budgets e a maioria dos padrões são por project, então criar um novo project para um experimento é o movimento normal e barato - não a cerimônia que uma AWS account é.
Service accounts: você personifica, você não assume
Na AWS, um role é um conjunto de permissões que um principal assume através do STS, limitado por uma trust policy. No GCP, o equivalente é o service account (SA), e ele funciona de forma diferente, o que confunde todo engenheiro AWS.
Um service account é tanto uma identidade quanto um recurso. Ele tem um email (deployer@acme-app-prod.iam.gserviceaccount.com), ele vive dentro de um project, e - crucialmente - ele tem sua própria IAM policy governando quem pode usá-lo. Essa segunda parte é a que não tem reflexo na AWS:
- Para agir como um service account, um principal precisa de um role no próprio SA -
roles/iam.serviceAccountTokenCreator(para criar tokens de curta duração e personificá-lo) ouroles/iam.serviceAccountUser(para anexá-lo a um recurso que você está criando, como uma VM ou um serviço Cloud Run). Esta é a concessão de dois lados que o pessoal da AWS esquece: dar ao seu principal de CI amplos direitos de project é inútil se ele não puder se tornar o SA de deployer. - Você personifica um SA pedindo um token (
generateAccessToken), não assumindo um role com um handshake de trust-policy. A permissão para personificar vive como um IAM binding comum no recurso SA - não há um documento de trust separado. - Service account keys existem e você deve evitá-las na maioria das vezes. Uma JSON key baixada é uma credencial de longa duração e um vetor clássico de vazamento; muitas orgs desabilitam a criação de chaves em toda a organização através da constraint mencionada anteriormente. As alternativas sem chave são as que você deve procurar.
- Keyless CI é Workload Identity Federation - a mesma ideia OIDC da federação OIDC da AWS. Suas GitHub Actions ou workload externa apresentam um token OIDC, um workload identity pool confia no emissor, e o GCP retorna credenciais de curta duração para um SA. Nenhum secret armazenado. (Dentro do GKE, o análogo é Workload Identity, que vincula um Kubernetes service account a um Google service account - o equivalente direto do IRSA da AWS.)
A tradução em uma linha: um AWS role que você assume via trust policy se torna um GCP service account que você personifica via um token-creator binding no SA.
O domínio de identidade: Cloud Identity, Workspace e a org
O GCP separa a identidade dos recursos, mas de forma muito mais suave do que o Azure. O organization node é criado contra um domínio verificado que é de propriedade de uma conta Cloud Identity ou Google Workspace. Esse diretório - users e groups - é administrado no Admin console (admin.google.com), uma superfície diferente do Cloud console onde você gerencia recursos.
- Users e groups são criados no diretório; o acesso é concedido no IAM. Você não cria um "GCP user" da mesma forma que cria um IAM user na AWS. O humano existe no Cloud Identity/Workspace (ou é federado do seu IdP), e você os referencia - idealmente como um group - em IAM bindings na árvore de recursos. A melhor prática é bindings para groups, nunca para users individuais.
- Não há um armazenamento "IAM users" independente como o da AWS. IdPs externos (Okta, Entra ID, e assim por diante) federam para o Cloud Identity; essa é a norma para acesso da força de trabalho.
- Duas armadilhas para memorizar: os membros especiais
allUsers(literalmente qualquer pessoa na internet, não autenticada) eallAuthenticatedUsers(qualquer pessoa com qualquer Google account). Vincular um role a qualquer um deles é como os buckets acidentalmente se tornam públicos. Trate-os da mesma forma que você trata umPrincipal: "*"em uma S3 bucket policy.
A analogia aproximada: a organization mais seu domínio Cloud Identity é grosseiramente "uma AWS Organization fundida com o diretório do IAM Identity Center" - mas o trabalho diário com recursos acontece através de IAM bindings na árvore, não através de políticas anexadas à identidade.
O faturamento é um objeto separado que você vincula a projects
Uma billing account no GCP é um recurso próprio - ela não é um nó na hierarquia org -> folder -> project. Projects se vinculam a uma billing account (cada project a exatamente uma), e uma única billing account pode financiar muitos projects.
- Ele tem seu próprio IAM.
roles/billing.admin,roles/billing.user,roles/billing.creatorresidem na billing account, separadas dos seus resource roles. Em particular, para anexar um novo project a uma billing account, você precisa deroles/billing.usernessa billing account - direitos amplos de project por si só não serão suficientes. - "Eu posso fazer deploy" não diz nada sobre "Eu posso criar um project cobrável". Para criar um project que possa incorrer em cobranças, você precisa de
resourcemanager.projectCreator(na org/folder) ebilling.user(na billing account). Se você perder o segundo, a criação do project terá um sucesso parcial em um project que não pode realmente executar nada.
Isso é mais suave do que a rígida parede do plano comercial do Azure - o faturamento do GCP está conectado ao Cloud IAM, então ele aparece nas mesmas interfaces gcloud e Terraform, em vez de um mundo totalmente separado. Mas ainda é um objeto distinto com roles distintos, e é a segunda surpresa mais comum de "mas eu sou um admin" depois das APIs desabilitadas.
Nomes, IDs e uma surpresa de rede
Cada recurso GCP tem um relative resource name como projects/acme-app-prod/zones/us-central1-a/instances/web-1 (e uma forma totalmente qualificada //compute.googleapis.com/...). O project ID viaja com cada linha de log e chamada de API - o mesmo trabalho que a account de um ARN faz na AWS - então, como no Azure, seus nomes de recurso podem omitir o que o project já codifica. Os mesmos nomes curtos podem se repetir com segurança em seus projects -dev, -qa e -prod.
A pegadinha de rede que vale a pena sinalizar de antemão, porque ela viola silenciosamente os instintos da AWS: uma VPC network no GCP é um recurso global, e suas subnets são regionais. Na AWS, uma VPC é limitada a uma região; no GCP, uma VPC abrange todas as regiões, e você cria subnets regionais dentro dela. Uma única VPC global com subnets regionais é o padrão, não uma configuração exótica de várias regiões - não recorra ao VPC peering para fazer o que uma subnet já lhe oferece.
O mapa rápido AWS -> GCP
Mantenha isso ao seu lado durante o primeiro mês:
- Organization -> organization. Mesma ideia, mas a org do GCP está vinculada ao seu domínio Cloud Identity/Workspace.
- Organizational Unit (OU) -> folder. Nó de agrupamento aninhável; folders podem conter folders.
- Account -> project. A unidade de isolamento, IAM e faturamento - mas leve e descartável, feita às dezenas.
- SCP (guardrail) -> Organization Policy constraint em um escopo org/folder/project - restringe o que pode existir ou ser configurado, herda para baixo.
- IAM identity-attached policy -> IAM binding
(member, role)em um nó da árvore. Nenhuma policy no user; a concessão reside no resource e herda para baixo. - IAM role que você assume (via STS + trust policy) -> service account que você personifica (via um token-creator binding no SA). Lembre-se da concessão de dois lados.
- Declaração
Denyexplícita -> IAM deny policy - um objeto separado, avaliado antes das permissões. - IRSA (IAM Roles for Service Accounts) -> Workload Identity (GKE) / Workload Identity Federation (CI externo) - a mesma ideia OIDC, sem chaves.
- "O serviço está simplesmente disponível" -> habilite sua API por project primeiro (
google_project_service). Sem equivalente na AWS. - ARN em logs -> o resource name (
projects/<id>/...); o contexto do project é estruturado, não codificado no nome.
Inicializando o estado do Terraform, traduzido
Aqui está um lugar onde seu runbook da AWS quase funciona, mas falha no passo zero.
O bootstrap da AWS que você conhece: cold-start um state backend na management account (estado local, depois migrar o backend para si mesmo), manter o estado dos backends por OU nesse backend raiz, e criar member accounts usando seus próprios backends. O invariante que o torna limpo é que você sempre pode fazer bootstrap a partir da management account, porque ela sempre existe e pode conter um S3 bucket.
O GCP quebra esse invariante na gênese da mesma forma que o Azure: o objeto que sempre existe é a organization, mas um nó de org não pode conter recursos. Um GCS bucket vive em um project, e um project precisa de um pai e (para fazer algo real) um link de faturamento e APIs habilitadas. Então, a "root account" do GCP é um seed project que você coroa conscientemente - o nome idiomático é algo como prj-bootstrap ou um Cloud Foundation Toolkit seed project.
O fluxo traduzido, quando a org e uma billing account já existem (o caso comum):
- Um cold-start, para sempre: crie o seed project imperativamente (
gcloud projects create), habilite as bootstrap APIs nele (cloudresourcemanager,cloudbilling,serviceusage,iam,storage), vincule o faturamento e crie o GCS state bucket com Terraform state local - entãoinit -migrate-statepara esse bucket. - Um bootstrap service account com roles de nível de org: conceda a ele
resourcemanager.projectCreator,billing.usere seus roles de admin de org-policy/IAM no organization node, para que ele possa criar e governar cada project downstream. - Todo o resto é um apply normal: projects adicionais, folders e seus recursos são criados pelo Terraform personificando esse bootstrap SA, o estado de cada project vivendo sob um
prefixno único GCS backend.
Do zero absoluto, a ordem é forçada - seed project primeiro, state bucket segundo - porque um backend é um GCS bucket e um bucket precisa de um project para existir. E há uma pequena complicação de ovo e galinha, assim como no Azure: o provider google precisa de um project e APIs habilitadas para fazer qualquer coisa, então você cria esse primeiro project e habilita suas APIs com uma chamada gcloud imperativa, e depois o adota no Terraform. (O módulo terraform-google-modules/bootstrap empacota exatamente essa dança de seed-project-plus-SA.)
E é aqui que o GCP é genuinamente mais simples do que a memória muscular da AWS: backend-in-seed-project mais resources-in-member não precisa de nenhuma da maquinaria de trust hub-and-spoke da AWS - sem role_arn de backend, sem assume_role de provider, sem trust policies de dois lados. Um service account de nível de org com os roles certos funciona em toda a org porque o IAM herda para baixo; o provider "salta" entre projects simplesmente definindo project; e ele se torna a identidade de deployer definindo impersonate_service_account. Cross-project é um parâmetro, não uma negociação de trust. (Você irá apertar isso mais tarde com custom roles, SAs por project e CI identities dedicadas - mas mesmo assim são role bindings em escopos, nunca um handshake de trust-policy.) Se você quiser se aprofundar na codificação de qualquer um dos lados, o exame HashiCorp Terraform Authoring & Operations Pro é construído exatamente em torno desses padrões de state e provider.
Os quatro pontos onde seus instintos AWS irão ativamente te enganar
Se você esquecer todo o resto, lembre-se disso:
- Não há policy no user. Pare de procurar pelo JSON anexado a uma identidade. As permissões são
(member, role)bindings na org, folder, project ou resource, e elas herdam para baixo. A concessão que você precisa pode estar três níveis acima. - Nada funciona até você habilitar a API. Seu primeiro 403 em um novo project geralmente é
API not enabled, não um role ausente. Todo serviço está desativado até você ativá-lo, por project. - Você personifica service accounts, você não assume roles. E o SA é um resource com sua própria access policy - dar ao seu principal amplos direitos de project é inútil sem um token-creator binding no SA.
- O faturamento é um objeto separado. "Eu posso fazer deploy de qualquer coisa" não diz nada sobre "Eu posso criar um project cobrável ou vincular uma billing account". Recurso diferente, roles diferentes -
billing.userna billing account, não project admin.
Quais certificações abordam cada lado
Governança de Cloud - hierarquia, identidade, guardrails e estado - é a espinha dorsal dos exames de arquitetura e administração em ambas as clouds, então estudar para eles também é a maneira mais rápida de fixar os conceitos acima. Se você já possui a credencial AWS, a do Google Cloud na mesma linha é seu próximo passo natural.
No lado AWS (o conhecimento do qual você está traduzindo):
- AWS Certified Cloud Practitioner (CLF-C02) - os fundamentos de accounts, IAM e Organizations.
- AWS Certified Solutions Architect - Associate (SAA-C03) - IAM, estrutura multi-account e arquitetura core.
- AWS Certified Solutions Architect - Professional (SAP-C02) - multi-account Organizations, SCPs e acesso cross-account em escala.
- AWS Certified Security - Specialty (SCS-C03) - profundidade de IAM, SCPs e gerenciamento de chaves.
No lado Google Cloud (o conhecimento para o qual você está traduzindo):
- Google Cloud Digital Leader - organizations, projects, IAM e faturamento em um nível fundamental.
- Google Cloud Associate Cloud Engineer - o plano do dia a dia: projects, IAM bindings, service accounts e
gcloud. - Google Cloud Professional Cloud Architect - a hierarquia org/folder/project, design de landing-zone e governança em escala.
- Google Cloud Professional Cloud Security Engineer - profundidade de IAM, org policy, segurança de service-account e gerenciamento de chaves.
Um caminho pragmático se você é certificado AWS hoje: comece pelo Cloud Digital Leader para mapear o vocabulário, depois pule para o Associate Cloud Engineer (que vive no plano de project e IAM que você mais usará), e adicione o Professional Cloud Architect ou Professional Cloud Security Engineer dependendo se seu trabalho se inclina para arquitetura ou segurança.
Conclusão
O GCP não é mais difícil que a AWS - ele é fatorado de forma diferente. A AWS anexa permissões a identidades, entrega uma account pesada com tudo ativado e concentra a maior parte da autoridade no IAM. O GCP pendura permissões em uma árvore de recursos que herda para baixo, oferece projects baratos e descartáveis que começam como telas em branco e faz você personificar service accounts em vez de assumir roles. Traduza os conceitos uma vez - policies se movem de identidades para a árvore, accounts se tornam projects com suas APIs desativadas, roles se tornam service accounts que você personifica, e o faturamento é um objeto separado que você vincula - e o resto é vocabulário. Pratique com as certificações acima, e as partes que pareciam negações arbitrárias começarão a ser lidas como um design coerente e deliberado.