<h2>Google Cloud Platform para DevOps: Uma Introdução Prática</h2>
<p>Bem-vindo a este guia completo sobre Google Cloud Platform (GCP) focado em DevOps. Se você trabalha com infraestrutura em nuvem, já deve ter percebido que GCP oferece um conjunto robusto de ferramentas que simplificam desde a orquestração de containers até o gerenciamento de bancos de dados. Este artigo vai além da teoria: você entenderá <em>por que</em> cada serviço existe e <em>como</em> usá-los em cenários reais.</p>
<p>Durante minha experiência profissional, vi equipes inteiras transformarem seus processos de deploy ao abraçarem os serviços certos do GCP. O segredo não é conhecer tudo, mas dominar os pilares: contenização com GKE, serverless com Cloud Run, dados persistentes com Cloud SQL e segurança através do IAM. Vamos começar.</p>
<h2>GKE: Kubernetes Gerenciado para Orquestração em Escala</h2>
<h3>O que é GKE e Por Que Você Precisa Dele</h3>
<p>Google Kubernetes Engine (GKE) é um serviço totalmente gerenciado que executa Kubernetes na GCP. Se você ainda pensa que Kubernetes é apenas uma ferramenta "legal", está perdendo a oportunidade de automatizar deploy, scaling e healing de aplicações. GKE remove a dor de gerenciar o control plane do Kubernetes — Google cuida disso para você.</p>
<p>Imagine que você tem uma aplicação web escrita em Go que recebe milhares de requisições por minuto. Você poderia executá-la em uma única VM, mas quando o tráfego dobra de repente? Você precisa de mais instâncias. Com GKE, você define quantas réplicas deseja, e o Kubernetes garante que esse número sempre seja mantido, recriando pods que falhem.</p>
<h3>Criando um Cluster GKE do Zero</h3>
<p>Vou mostrar como provisionar um cluster GKE usando a CLI <code>gcloud</code>. Você precisará ter o GCP configurado com um projeto válido.</p>
<pre><code class="language-bash"># Defina o projeto
export PROJECT_ID="seu-projeto-gcp"
export REGION="us-central1"
export CLUSTER_NAME="producao-cluster"
gcloud config set project $PROJECT_ID
Crie o cluster
gcloud container clusters create $CLUSTER_NAME \
--region=$REGION \
--num-nodes=3 \
--machine-type=n1-standard-2 \
--enable-autoscaling \
--min-nodes=3 \
--max-nodes=10 \
--enable-autorepair \
--enable-autoupgrade
Obtenha as credenciais do cluster
gcloud container clusters get-credentials $CLUSTER_NAME --region=$REGION</code></pre>
<p>Após executar esses comandos, você terá um cluster Kubernetes com 3 nós que pode escalar automaticamente até 10 nós dependendo da carga. O <code>--enable-autorepair</code> garante que nós com falha sejam substituídos automaticamente.</p>
<h3>Implantando uma Aplicação no GKE</h3>
<p>Agora vou demonstrar como fazer deploy de uma aplicação Node.js simples no GKE. Primeiro, o Dockerfile:</p>
<pre><code class="language-dockerfile">FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]</code></pre>
<p>E o <code>server.js</code>:</p>
<pre><code class="language-javascript">const express = require('express');
const app = express();
app.get('/health', (req, res) => {
res.json({ status: 'healthy', timestamp: new Date() });
});
app.get('/api/data', (req, res) => {
res.json({ data: 'Exemplo de resposta', version: '1.0' });
});
app.listen(3000, () => {
console.log('Servidor rodando na porta 3000');
});</code></pre>
<p>Agora, construa a imagem e envie para Google Container Registry:</p>
<pre><code class="language-bash"># Configure o Docker para usar gcloud como autenticador
gcloud auth configure-docker
Construa a imagem
docker build -t gcr.io/$PROJECT_ID/nodejs-app:1.0 .
Envie para o registro
docker push gcr.io/$PROJECT_ID/nodejs-app:1.0</code></pre>
<p>Para fazer deploy, crie um arquivo <code>deployment.yaml</code>:</p>
<pre><code class="language-yaml">apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-app
labels:
app: nodejs-app
spec:
replicas: 3
selector:
matchLabels:
app: nodejs-app
template:
metadata:
labels:
app: nodejs-app
spec:
containers:
- name: app
image: gcr.io/seu-projeto-gcp/nodejs-app:1.0
ports:
- containerPort: 3000
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: nodejs-app-service
spec:
selector:
app: nodejs-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer</code></pre>
<p>Faça o deploy:</p>
<pre><code class="language-bash">kubectl apply -f deployment.yaml
Monitore o deployment
kubectl get deployments
kubectl get pods
kubectl get services
Obtenha o IP externo do LoadBalancer
kubectl get service nodejs-app-service</code></pre>
<p>O Deployment define 3 réplicas que rodam automaticamente, com recursos de CPU e memória limite. Os probes de health garantem que o Kubernetes recrie pods que falharem. Este é um padrão que vejo em todas as empresas profissionais que trabalham com Kubernetes.</p>
<h2>Cloud Run: Serverless para Aplicações Stateless</h2>
<h3>Quando e Por Que Usar Cloud Run</h3>
<p>Cloud Run é a resposta da Google para "quero rodar meu container, mas não quero pensar em infraestrutura". Você envia um container, define quantidades máximas de requisições concorrentes, e pronto — o serviço escala automaticamente de zero para milhões de requisições. Você paga apenas pelo tempo em que está processando requisições, em unidades de 100 milissegundos.</p>
<p>Isso é ideal para APIs de baixa latência, webhooks, processamento de eventos ou jobs que não rodam continuamente. Se você tem uma aplicação que fica ociosa por horas, Cloud Run economiza muito dinheiro em comparação com manter um cluster GKE rodando.</p>
<h3>Implantando uma API REST no Cloud Run</h3>
<p>Vou criar uma API Python simples usando Flask e fazer deploy no Cloud Run.</p>
<pre><code class="language-python"># app.py
from flask import Flask, jsonify, request
import os
from datetime import datetime
app = Flask(__name__)
@app.route('/health', methods=['GET'])
def health():
return jsonify({'status': 'ok'}), 200
@app.route('/api/procesar', methods=['POST'])
def procesar():
data = request.get_json()
if not data or 'entrada' not in data:
return jsonify({'error': 'Campo "entrada" é obrigatório'}), 400
Simula processamento
resultado = {
'entrada': data['entrada'],
'saida': data['entrada'].upper(),
'timestamp': datetime.now().isoformat(),
'versao': os.getenv('VERSION', '1.0')
}
return jsonify(resultado), 200
@app.route('/api/status', methods=['GET'])
def status():
return jsonify({
'servico': 'api-processamento',
'status': 'operacional',
'instancia': os.getenv('HOSTNAME', 'desconhecida')
}), 200
if __name__ == '__main__':
port = int(os.getenv('PORT', 8080))
app.run(host='0.0.0.0', port=port, debug=False)</code></pre>
<p>Crie o <code>requirements.txt</code>:</p>
<pre><code>Flask==3.0.0
Werkzeug==3.0.0</code></pre>
<p>Crie um <code>Dockerfile</code>:</p>
<pre><code class="language-dockerfile">FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
ENV PORT=8080
CMD ["python", "app.py"]</code></pre>
<p>Agora, faça o deploy no Cloud Run diretamente:</p>
<pre><code class="language-bash"># Você pode fazer deploy diretamente do seu código-fonte
gcloud run deploy api-processamento \
--source . \
--platform managed \
--region us-central1 \
--allow-unauthenticated \
--set-env-vars VERSION=1.0 \
--memory 512Mi \
--timeout 60
Teste o serviço
curl https://api-processamento-<seu-hash>.run.app/api/status
POST com dados
curl -X POST https://api-processamento-<seu-hash>.run.app/api/procesar \
-H "Content-Type: application/json" \
-d '{"entrada": "olá mundo"}'</code></pre>
<p>A beleza do Cloud Run é que você não escreve YAML. Você apenas dá deploy. O serviço escala automaticamente — se receber 0 requisições por 15 minutos, as instâncias são destruídas. Quando uma requisição chega, novas instâncias são criadas em segundos.</p>
<h3>Usando Cloud Run com Variáveis de Ambiente e Secrets</h3>
<p>Para aplicações em produção, você não deve hardcodar credenciais. Use Google Secret Manager:</p>
<pre><code class="language-bash"># Crie um secret para a chave de API
echo -n "sua-chave-api-secreta" | gcloud secrets create chave-api --data-file=-
Atualize o serviço para usar o secret
gcloud run services update api-processamento \
--set-env-vars CHAVE_API=projects/SEU_PROJECT_ID/secrets/chave-api/versions/latest \
--region us-central1</code></pre>
<p>Na aplicação Python, acesse assim:</p>
<pre><code class="language-python">import os
from google.cloud import secretmanager
def acessar_secret(secret_id, version_id='latest'):
client = secretmanager.SecretManagerServiceClient()
project_id = os.getenv('GCP_PROJECT')
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
response = client.access_secret_version(request={"name": name})
return response.payload.data.decode("UTF-8")
chave = acessar_secret('chave-api')</code></pre>
<h2>Cloud SQL: Banco de Dados Gerenciado e Confiável</h2>
<h3>Entendendo Cloud SQL e Seus Benefícios</h3>
<p>Cloud SQL é um serviço gerenciado para MySQL, PostgreSQL e SQL Server. Ao contrário de rodar um banco em uma VM, você obtém backups automáticos, patches de segurança aplicados automaticamente, replicação de alta disponibilidade e failover automático. Na minha experiência, a segurança adicional e a eliminação de tarefas operacionais justificam completamente o uso.</p>
<p>A decisão entre PostgreSQL e MySQL no Cloud SQL deve levar em conta suas necessidades. PostgreSQL é mais robusto e oferece features avançadas como JSONB, arrays nativos e extensões. MySQL é mais simples e direto. Para a maioria dos casos modernos, recomendo PostgreSQL.</p>
<h3>Criando uma Instância Cloud SQL</h3>
<pre><code class="language-bash"># Variáveis
export INSTANCE_NAME="producao-db"
export REGION="us-central1"
export ROOT_PASSWORD="SenhaForte123!"
Crie a instância PostgreSQL
gcloud sql instances create $INSTANCE_NAME \
--database-version=POSTGRES_15 \
--region=$REGION \
--tier=db-custom-2-8192 \
--storage-type=PD_SSD \
--storage-size=50GB \
--backup-start-time=03:00 \
--enable-bin-log \
--retained-backups-count=30 \
--transaction-log-retention-days=7 \
--root-password=$ROOT_PASSWORD
Crie um banco de dados
gcloud sql databases create app_producao \
--instance=$INSTANCE_NAME
Crie um usuário com permissões restritas
gcloud sql users create app_user \
--instance=$INSTANCE_NAME \
--password=SenhaApp456!</code></pre>
<h3>Conectando uma Aplicação Python ao Cloud SQL</h3>
<p>Use o Cloud SQL Proxy para conectar de forma segura. Primeiro, na sua aplicação (usando SQLAlchemy):</p>
<pre><code class="language-python"># app.py
import os
from flask import Flask, jsonify
from sqlalchemy import create_engine, text
from google.cloud.sql.connector import Connector
import sqlalchemy
app = Flask(__name__)
Inicialize o conector
connector = Connector()
def getconn():
return connector.connect(
"seu-projeto:us-central1:producao-db",
"pg8000",
user="app_user",
password=os.getenv("DB_PASSWORD"),
db="app_producao",
)
engine = create_engine(
"postgresql+pg8000://",
creator=getconn,
)
@app.route('/api/usuarios', methods=['GET'])
def listar_usuarios():
with engine.connect() as conn:
result = conn.execute(text("SELECT id, nome, email FROM usuarios LIMIT 10"))
usuarios = [
{"id": row[0], "nome": row[1], "email": row[2]}
for row in result
]
return jsonify(usuarios)
@app.route('/api/usuarios', methods=['POST'])
def criar_usuario():
from flask import request
data = request.get_json()
with engine.connect() as conn:
conn.execute(
text(
"INSERT INTO usuarios (nome, email) VALUES (:nome, :email)"
),
{"nome": data['nome'], "email": data['email']}
)
conn.commit()
return jsonify({"status": "usuario criado"}), 201
@app.route('/health', methods=['GET'])
def health():
try:
with engine.connect() as conn:
conn.execute(text("SELECT 1"))
return jsonify({"status": "ok"}), 200
except Exception as e:
return jsonify({"status": "erro", "detalhes": str(e)}), 500
if __name__ == '__main__':
port = int(os.getenv('PORT', 8080))
app.run(host='0.0.0.0', port=port)</code></pre>
<p>Instale as dependências:</p>
<pre><code class="language-bash">pip install Flask SQLAlchemy cloud-sql-python-connector pg8000</code></pre>
<p>Quando deployar no Cloud Run, adicione a variável de ambiente:</p>
<pre><code class="language-bash">gcloud run deploy app-api \
--source . \
--region us-central1 \
--set-env-vars DB_PASSWORD=SenhaApp456! \
--add-cloudsql-instances seu-projeto:us-central1:producao-db</code></pre>
<h3>Backup e Recuperação</h3>
<p>Cloud SQL gerencia backups automaticamente, mas é bom saber como restaurar:</p>
<pre><code class="language-bash"># Liste backups disponíveis
gcloud sql backups list --instance=$INSTANCE_NAME
Crie um backup sob demanda
gcloud sql backups create \
--instance=$INSTANCE_NAME \
--description="Backup manual antes da migração"
Restaure para uma nova instância (não sobrescreve a existente)
gcloud sql backups restore <backup-id> \
--backup-instance=$INSTANCE_NAME \
--restore-instance=producao-db-restored</code></pre>
<h2>IAM: Controle de Acesso e Segurança</h2>
<h3>Princípios de Segurança com IAM</h3>
<p>Identity and Access Management (IAM) é o sistema de permissões do GCP. Muitos começam dando <code>editor</code> para tudo, e isso é um risco enorme. O princípio correto é "menor privilégio": cada usuário ou serviço deve ter apenas as permissões que precisa.</p>
<p>No GCP, você trabalha com três conceitos principais: <strong>Member</strong> (quem), <strong>Role</strong> (o que pode fazer), e <strong>Resource</strong> (em quais recursos). Uma combinação desses é chamada "binding". Por exemplo: "o usuário joão@empresa.com tem o papel <code>Cloud Run Developer</code> no projeto meu-app".</p>
<h3>Criando Contas de Serviço para Aplicações</h3>
<p>Contas de serviço são identidades para aplicações, não para pessoas. Toda aplicação deve usar uma conta de serviço específica com permissões mínimas.</p>
<pre><code class="language-bash"># Crie uma conta de serviço para a aplicação API
gcloud iam service-accounts create app-api-account \
--display-name="Conta de serviço para API de processamento"
Obtenha o email da conta
export SERVICE_ACCOUNT="app-api-account@seu-projeto.iam.gserviceaccount.com"
Conceda permissões específicas para Cloud SQL
gcloud projects add-iam-policy-binding seu-projeto \
--member=serviceAccount:$SERVICE_ACCOUNT \
--role=roles/cloudsql.client
Permissão para acessar Cloud Storage (se necessário)
gcloud projects add-iam-policy-binding seu-projeto \
--member=serviceAccount:$SERVICE_ACCOUNT \
--role=roles/storage.objectViewer
Permissão para logs
gcloud projects add-iam-policy-binding seu-projeto \
--member=serviceAccount:$SERVICE_ACCOUNT \
--role=roles/logging.logWriter
Crie uma chave para a conta (salve de forma segura!)
gcloud iam service-accounts keys create credentials.json \
--iam-account=$SERVICE_ACCOUNT</code></pre>
<p>Agora, configure a aplicação para usar essa conta:</p>
<pre><code class="language-bash">export GOOGLE_APPLICATION_CREDENTIALS="/caminho/para/credentials.json"
Ou, se rodar no GCP, o serviço detecta automaticamente:
gcloud run deploy app-api \
--source . \
--region us-central1 \
--service-account=$SERVICE_ACCOUNT</code></pre>
<h3>Controlando Acesso a Cloud Run</h3>
<p>Nem todos devem poder invocar seus serviços Cloud Run. Use IAM para controlar:</p>
<pre><code class="language-bash"># Permita que apenas um usuário invoque o serviço
gcloud run services add-iam-policy-binding api-processamento \
--member=user:developer@empresa.com \
--role=roles/run.invoker \
--region=us-central1
Permita que um grupo invoque
gcloud run services add-iam-policy-binding api-processamento \
--member=group:devops@empresa.com \
--role=roles/run.invoker \
--region=us-central1
Veja todas as bindings
gcloud run services get-iam-policy api-processamento \
--region=us-central1</code></pre>
<h3>Auditoria e Logging</h3>
<p>Toda ação importante deve ser registrada. O Cloud Audit Logs registra automaticamente quem fez o quê:</p>
<pre><code class="language-bash"># Veja logs de auditoria (Cloud Shell ou CLI)
gcloud logging read \
"protoPayload.methodName=storage.buckets.delete" \
--limit 5 \
--format json
Crie um sink para enviar logs importantes para BigQuery
gcloud logging sinks create audit-sink bigquery.googleapis.com/projects/seu-projeto/datasets/audit_logs \
--log-filter='protoPayload.authenticationInfo.principalEmail="usuario@empresa.com"'</code></pre>
<h3>Exemplo Prático: Estrutura Segura Completa</h3>
<p>Aqui está como estruturar um projeto seguro do zero:</p>
<pre><code class="language-bash"># Projeto: meu-app (você já tem)
export PROJECT_ID="meu-app"
export REGION="us-central1"
1. Crie contas de serviço para cada componente
gcloud iam service-accounts create gke-cluster-account \
--display-name="Conta para GKE"
gcloud iam service-accounts create cloud-run-account \
--display-name="Conta para Cloud Run"
gcloud iam service-accounts create database-account \
--display-name="Conta para acesso a banco de dados"
2. Atribua papéis específicos
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:gke-cluster-account@$PROJECT_ID.iam.gserviceaccount.com \
--role=roles/container.developer
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:cloud-run-account@$PROJECT_ID.iam.gserviceaccount.com \
--role=roles/run.admin
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:database-account@$PROJECT_ID.iam.gserviceaccount.com \
--role=roles/cloudsql.client
3. Para humanos, use grupos (melhor que usuários individuais)
gcloud iam service-accounts add-iam-policy-binding \
cloud-run-account@$PROJECT_ID.iam.gserviceaccount.com \
--member=group:devops@empresa.com \
--role=roles/iam.serviceAccountUser
4. Ative e revise Cloud Audit Logs no console GCP
Navegue para: Segurança > Audit Logs
Garanta que os logs administrativos, de dados e de eventos de sistema estejam ativos</code></pre>
<h2>Conclusão</h2>
<p>Você aprendeu que <strong>GKE é para aplicações stateful e complexas que precisam de controle fino</strong> — use quando tem múltiplos microsserviços, state persistente entre requisições, ou necessidade de operações cron complexas. <strong>Cloud Run é para APIs e jobs stateless que podem dormir</strong> — escolha quando quer simplicidade, custo reduzido, e scaling automático completo.</p>
<p>O segundo aprendizado foi que <strong>Cloud SQL elimina dor operacional real</strong> — você não gerencia upgrades, backups ou replicação. Use-o em produção sem hesitação. E finalmente, <strong>IAM não é opcional: é o alicerce de segurança</strong> do seu ambiente. Toda conta deve ter apenas as permissões que precisa, e isso se aplica tanto a usuários quanto a contas de serviço.</p>
<p>A jornada DevOps no GCP é sobre automação, segurança e economia. Esses quatro serviços — GKE, Cloud Run, Cloud SQL e IAM — formam a base sólida que você precisa. O resto vem com experiência.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://cloud.google.com/kubernetes-engine/docs" target="_blank" rel="noopener noreferrer">Documentação Google Kubernetes Engine (GKE)</a></li>
<li><a href="https://cloud.google.com/run/docs/quickstarts/build-and-deploy" target="_blank" rel="noopener noreferrer">Cloud Run: Quickstart</a></li>
<li><a href="https://cloud.google.com/sql/docs/postgres/best-practices" target="_blank" rel="noopener noreferrer">Cloud SQL: Best Practices</a></li>
<li><a href="https://cloud.google.com/iam/docs/understanding-custom-roles" target="_blank" rel="noopener noreferrer">Cloud IAM: Understanding Custom Roles</a></li>
<li><a href="https://cloud.google.com/python/docs" target="_blank" rel="noopener noreferrer">Google Cloud Python Client Libraries</a></li>
</ul>
<p><!-- FIM --></p>