Fazer deploy de aplicações na AWS tem fama: poderoso, flexível… e vez ou outra capaz de transformar uma tarde tranquila em uma aventura inesperada. Entre roles de IAM, imagens de container e decisões de rede, é fácil sentir que você precisa de mapa e bússola só para colocar um “Hello, world” no ar.
É aí que entra o AWS App Runner. A proposta é um caminho mais simples: você traz a sua aplicação, aponta para um container ou para um repositório de código, e a AWS cuida do trabalho pesado, incluindo escala, load balancing e gestão de infraestrutura.
Neste artigo, você vai percorrer o processo de deploy de uma aplicação FastAPI no AWS App Runner, com foco em um setup limpo e pronto para produção, sem complexidade desnecessária.
Se você gosta de APIs rápidas, menos arquivos YAML e deploys que não exigem sacrifício ritual, está no lugar certo.
Configurações na AWS
Antes de escrever qualquer código, é preciso criar alguns recursos básicos na AWS. Essas configurações permitem que o App Runner puxe a imagem do container com segurança e execute a aplicação FastAPI.
Repositório no Elastic Container Registry
Primeiro, crie um repositório para armazenar a imagem Docker da aplicação FastAPI.
- Vá em Amazon ECR → Create repository.
- Escolha um nome para o repositório. Neste artigo, vamos usar: fastapi-app-runner
- Clique em Create repository.
Depois de criar, copie e guarde o Repository URI. Ele será necessário mais adiante, na hora de fazer o build e o push da imagem Docker.
A role do App Runner
O App Runner precisa de permissão explícita para puxar imagens do Amazon ECR. Esse acesso é concedido criando uma role no IAM.
- Vá em IAM → Roles → Create role.
- Selecione Custom trust policy.
- Cole o JSON abaixo no editor de policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "apprunner.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}Code language: JSON / JSON with Comments (json)
- Clique em Next.
- Na página Permissions, busque e anexe a policy: AWSAppRunnerServicePolicyForECRAccess
- Clique em Next, dê um nome significativo para a role (por exemplo, AppRunnerECRAccessRole) e clique em Create role.
Leia também: Construindo redes neurais do zero
Criando o serviço no App Runner
Com os pré-requisitos da AWS prontos, chegou a hora de criar o serviço do App Runner que vai rodar a aplicação FastAPI. Siga os passos abaixo:
- Vá em AWS App Runner → Create service.
- Em Repository type, selecione Container registry.
- Em Provider, escolha Amazon ECR. Cole o URI do repositório ECR criado na seção anterior e acrescente a tag :latest da imagem
- Em Deployment trigger, selecione Automatic. Com essa opção ativada, cada nova imagem enviada para o ECR dispara automaticamente um novo deploy no App Runner.
- Selecione Use existing service role e escolha a role do IAM criada antes. É ela que permite ao App Runner puxar imagens do ECR.
- Clique em Next para abrir a página Configure service.
- Dê um nome ao seu serviço.
- Para simplificar, mantenha as configurações padrão desta página. Essas opções controlam tamanho de instância, comportamento de escala e roles adicionais do IAM, temas mais avançados e fora do escopo deste artigo. Vamos tratar deles em um post futuro.
- Revise a configuração e clique em Create & deploy.
Assim que o serviço for criado e o deploy terminar, o App Runner passa a executar a sua aplicação FastAPI conteinerizada. Daqui em diante, o foco é adaptar o código da aplicação para funcionar bem com o App Runner.
Leia também: Além do “vibe coding”: engenharia com IA e Cursor
A base do CI/CD: conectando o GitHub à AWS
Para automatizar o processo de build e deploy, é preciso configurar no GitHub as credenciais da AWS e as variáveis específicas de cada ambiente. Isso permite que o workflow do GitHub Actions se autentique na AWS e envie imagens Docker para o Amazon ECR.
Crie um ambiente no GitHub
Usar ambientes ajuda a isolar credenciais e aplicar controles extras, como revisores obrigatórios ou secrets específicos de cada ambiente.
- Acesse o seu repositório no GitHub.
- Vá em Settings → Environments.
- Clique em New environment.
- Dê um nome ao ambiente (por exemplo, production ou staging) e salve.
Gerenciando credenciais da AWS e variáveis de deploy com segurança
Adicione os secrets do ambiente
Com o ambiente criado, o próximo passo é adicionar os secrets que o pipeline de CI/CD precisa.
- Abra o ambiente que você acabou de criar.
- Em Environment secrets, clique em Add secret.
- Adicione os seguintes secrets: AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY, AWS_REGION, ECR_REPOSITORY_URI. Leia este artigo para obter as variáveis KEY.
Garanta que as credenciais do IAM usadas aqui tenham permissão para autenticar no ECR e enviar imagens para o repositório.
Boas práticas de segurança para CI/CD
- Guarde credenciais apenas como secrets do GitHub. Nunca faça commit delas no repositório.
- Use um usuário ou uma role do IAM dedicados, com permissões mínimas, limitadas ao acesso ao ECR.
- Se possível, considere usar autenticação baseada em OIDC com o GitHub Actions para evitar credenciais de longa duração na AWS. Essa abordagem é mais segura e mais adequada a ambientes de produção.
Com o ambiente e os secrets configurados no GitHub, chegou a hora de criar o workflow do GitHub Actions que faz o build da imagem Docker e a envia automaticamente para o Amazon ECR.
Leia também: Como usar Selenium para web scraping no AWS Lambda
Mudanças no código: adaptando a aplicação para rodar no App Runner
Vamos começar pelo arquivo responsável por instanciar a aplicação FastAPI. O trecho de código abaixo mostra um setup mínimo de FastAPI, expondo um único endpoint GET /health.
import os
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.sessions import SessionMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.add_middleware(SessionMiddleware, secret_key=os.getenv("JWT_SECRET_KEY", "default"))
@app.get("/health")
async def health_check():
"""Health check endpoint."""
return {"status": "ok"}Code language: JavaScript (javascript)
Agora, veja o Dockerfile. Ele é propositalmente simples: instala as dependencies com o gerenciador de pacotes uv, define o diretório de trabalho e chama o script entrypoint.sh. Preste atenção especial na porta exposta, que precisa coincidir com a porta configurada no AWS App Runner (8080 por padrão).
FROM python:3.12.11-slim-bookworm AS builder
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
WORKDIR /app
ENV PATH="/app/.venv/bin:$PATH"
ENV UV_LINK_MODE=copy
COPY pyproject.toml uv.lock .python-version ./
RUN uv sync --locked --no-dev
RUN uv pip install --system alembic
COPY . .
FROM python:3.12.11-slim-bookworm
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
RUN apt-get update && \
apt-get upgrade -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN pip install --upgrade pip setuptools
WORKDIR /app
ENV PATH="/app/.venv/bin:$PATH"
COPY --from=builder /app /app
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
EXPOSE 8080
ENTRYPOINT ["/entrypoint.sh"]Code language: JavaScript (javascript)
O arquivo docker-compose.yml também é direto. Ele referencia o Dockerfile, expõe as portas do container e carrega as variáveis de ambiente do arquivo .env.
services:
singuessr:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8000"
env_file:
- .envCode language: CSS (css)
Por fim, o script entrypoint.sh sobe o servidor Uvicorn, escutando na porta 8080.
#!/bin/sh
set -e
echo "Starting application..."
uv run uvicorn main:app --host 0.0.0.0 --port 8080Code language: PHP (php)
Automatizando build e deploy com GitHub Actions
Crie um arquivo chamado .github/workflows/app-runner-deploy.yml na raiz do projeto e adicione a configuração abaixo. Esse workflow define o pipeline do GitHub Actions responsável pelo deploy. Ele executa os seguintes passos: autentica na AWS, faz o build da imagem Docker, aplica a tag e envia a imagem para o Amazon ECR.
name: AWS App Runner Deploy Develop
on:
push:
branches:
- main # ← branch name
jobs:
deploy:
name: FastAPI deployment to AWS App Runner
runs-on: ubuntu-latest
environment: Production # ← Github environment
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Login to Amazon ECR
uses: aws-actions/amazon-ecr-login@v1
- name: Build Docker image
run: |
docker build \
-t fastapi-app-runner:latest \
-f Dockerfile .
- name: Tag Docker image
run: |
docker tag fastapi-app-runner:latest \
${{ secrets.ECR_REPOSITORY_URI }}:latest
- name: Push Docker image to ECR
run: |
docker push ${{ secrets.ECR_REPOSITORY_URI }}:latestCode language: PHP (php)
Depois de fazer o commit e o push das suas mudanças para a branch escolhida (neste exemplo, a branch main), a execução do workflow aparece na aba Actions. Se tudo estiver configurado corretamente, todos os passos vão terminar com sucesso.

O resultado final é uma imagem Docker disponível no seu repositório do Amazon ECR.

Deploy no App Runner: disparando e acompanhando publicações automáticas
Depois que você envia o código para a branch definida no workflow do GitHub Actions, o deploy no App Runner é disparado automaticamente. Você acompanha o processo e consulta todos os logs de execução direto no console do serviço do App Runner.
O deploy deve terminar em poucos minutos.

Para testar a aplicação, acesse a URL clicando em Default domain e chame, por exemplo, o endpoint /docs para ver a documentação da API.

Considerações finais e próximos passos
O AWS App Runner oferece um equilíbrio convincente entre simplicidade e robustez operacional. Para aplicações conteinerizadas como serviços FastAPI, ele elimina boa parte do overhead tradicional de gestão de infraestrutura e ainda se integra de forma limpa ao restante do ecossistema AWS.
Por que o App Runner funciona bem com FastAPI
- Overhead operacional mínimo: não é preciso gerenciar clusters, load balancers ou políticas de escala manualmente.
- Suporte nativo a containers: a integração direta com o Amazon ECR simplifica o pipeline de deploy.
- Escala automática: o serviço sobe e desce conforme o tráfego, sem configuração adicional.
- Segurança e rede embutidas: HTTPS, load balancing e isolamento de serviço ficam por conta da AWS.
- Ciclos de iteração curtos: combinado com o GitHub Actions, o deploy fica previsível e repetível.
Para muitos serviços de backend e APIs, o App Runner acerta o ponto entre plataformas totalmente gerenciadas e soluções mais complexas como ECS ou EKS.
Leia também: Boas práticas de FinOps na AWS: como cortar e otimizar custos de cloud
Próximos passos: escala, segurança e melhorias operacionais
Este artigo foca em um setup simples e funcional, mas há várias frentes que valem a exploração seguinte:
- Ajuste fino da configuração de instância: o App Runner permite ajustar CPU e memória, limites de concorrência e comportamento de auto-scaling. Essas opções são essenciais para otimizar performance e custo conforme o tráfego cresce.
- Infraestrutura como código com Terraform: gerenciar serviços do App Runner, roles do IAM e repositórios do ECR com Terraform melhora reprodutibilidade e governança. Também deixa setups com vários ambientes (staging, produção) mais fáceis de manter e revisar.
- Melhorias de segurança: considere trocar as credenciais estáticas da AWS no GitHub Actions por autenticação baseada em OIDC e apertar as permissões do IAM seguindo o princípio do menor privilégio.
- Observabilidade e monitoramento: integre logs, métricas e alarmes do Amazon CloudWatch para ganhar visibilidade sobre o comportamento e a performance da aplicação.
Em resumo, o App Runner é um excelente ponto de entrada para rodar aplicações FastAPI em nível de produção na AWS. Conforme os requisitos crescem, você adiciona controle e automação aos poucos, sem abrir mão da simplicidade que torna o App Runner atraente desde o começo.
