---
title: "Go e AWS: Deploy de Aplicações na Nuvem"
url: "https://golang.com.br/tutoriais/go-aws-deploy/"
markdown_url: "https://golang.com.br/tutoriais/go-aws-deploy.MD"
description: "Guia completo de deployment de aplicações Go na AWS: EC2, Lambda, S3, RDS e melhores práticas de infraestrutura em nuvem"
date: "2026-02-11"
author: "Hugo Developer"
---

# Go e AWS: Deploy de Aplicações na Nuvem

Guia completo de deployment de aplicações Go na AWS: EC2, Lambda, S3, RDS e melhores práticas de infraestrutura em nuvem


# Go e AWS: Deploy de Aplicações na Nuvem

A AWS (Amazon Web Services) é a maior plataforma de cloud computing do mundo, oferecendo mais de 200 serviços. Quando combinada com Go, uma linguagem compilada com excelente performance e baixo consumo de recursos, você obtém uma stack poderosa e econômica para aplicações em produção.

Neste guia completo, você aprenderá desde os conceitos básicos até técnicas avançadas para deploy de aplicações Go na AWS, incluindo EC2, Lambda, S3, RDS e muito mais.

## Por que usar Go na AWS?

Antes de mergulharmos nas implementações práticas, vamos entender porque Go e AWS formam uma combinação tão eficiente:

### Vantagens do Go para Cloud Native

1. **Binário único**: Deploy simples com um único arquivo executável
2. **Startup rápido**: Ideal para serverless (Lambda) onde cada milissegundo importa
3. **Baixo consumo de memória**: Econômico para serviços que rodam 24/7
4. **Concorrência nativa**: Goroutines são perfeitas para serviços distribuídos
5. **Excelente ecossistema**: AWS SDK for Go v2 é moderno e bem documentado

### Comparação: Go vs outras linguagens na AWS

| Característica | Go | Python | Node.js | Java |
|---------------|-----|--------|---------|------|
| Cold Start (Lambda) | ~10-50ms | ~100-500ms | ~50-200ms | ~500ms-2s |
| Memória típica | 10-50MB | 50-150MB | 50-100MB | 100-500MB |
| Tempo de build | Rápido | N/A | Rápido | Lento |
| Concorrência | Nativa | GIL limita | Event loop | Threads pesadas |

## Configurando o AWS SDK para Go

O AWS SDK for Go v2 é a ferramenta oficial para interagir com os serviços AWS. Vamos configurá-lo corretamente.

### Instalação

```bash
go get github.com/aws/aws-sdk-go-v2
go get github.com/aws/aws-sdk-go-v2/config
go get github.com/aws/aws-sdk-go-v2/credentials
```

### Configuração de Credenciais

A AWS oferece várias formas de autenticação. A mais segura para produção é usando IAM Roles, mas para desenvolvimento local, usamos AWS CLI ou variáveis de ambiente.

#### Opção 1: Config file (~/.aws/credentials)

```ini
[default]
aws_access_key_id = AKIA...
aws_secret_access_key = ...
region = us-east-1

[producao]
aws_access_key_id = AKIA...
aws_secret_access_key = ...
region = sa-east-1
```

#### Opção 2: Variáveis de ambiente

```bash
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_REGION="sa-east-1"
```

### Criando um Cliente AWS

```go
package main

import (
    "context"
    "log"
    
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/ec2"
)

func main() {
    ctx := context.Background()
    
    // Carrega configuração do ambiente
    cfg, err := config.LoadDefaultConfig(ctx,
        config.WithRegion("sa-east-1"),
    )
    if err != nil {
        log.Fatalf("Falha ao carregar configuração AWS: %v", err)
    }
    
    // Cria cliente EC2
    client := ec2.NewFromConfig(cfg)
    
    // Agora você pode usar o cliente
    listarInstancias(ctx, client)
}
```

## Deploy em EC2: Máquinas Virtuais

EC2 (Elastic Compute Cloud) é o serviço de máquinas virtuais da AWS. É ideal para aplicações que precisam rodar continuamente.

### Preparando sua Aplicação

Primeiro, compile sua aplicação para Linux (arquitetura x86_64 ou ARM):

```bash
# Build para EC2 (Linux x86_64)
GOOS=linux GOARCH=amd64 go build -o meuapp-linux-amd64 .

# Ou para instâncias ARM (melhor custo-benefício)
GOOS=linux GOARCH=arm64 go build -o meuapp-linux-arm64 .
```

### Script de User Data para Bootstrap

O User Data permite configurar automaticamente a instância no primeiro boot:

```bash
#!/bin/bash

# Atualiza o sistema
apt-get update && apt-get upgrade -y

# Cria usuário para a aplicação
useradd -r -s /bin/false appuser

# Diretório da aplicação
mkdir -p /opt/meuapp

# Baixa a aplicação (de S3 ou GitHub Releases)
aws s3 cp s3://meu-bucket-deploy/meuapp-linux-amd64 /opt/meuapp/meuapp
chmod +x /opt/meuapp/meuapp

# Cria arquivo de serviço systemd
cat > /etc/systemd/system/meuapp.service << 'EOF'
[Unit]
Description=Minha Aplicacao Go
After=network.target

[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/meuapp
ExecStart=/opt/meuapp/meuapp
Restart=always
RestartSec=5
Environment=PORT=8080
Environment=AWS_REGION=sa-east-1

[Install]
WantedBy=multi-user.target
EOF

# Inicia o serviço
systemctl daemon-reload
systemctl enable meuapp
systemctl start meuapp
```

### Criando Instância EC2 com Go

```go
package main

import (
    "context"
    "encoding/base64"
    "fmt"
    "log"
    
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/ec2"
    "github.com/aws/aws-sdk-go-v2/service/ec2/types"
)

func criarInstanciaEC2(ctx context.Context, client *ec2.Client) error {
    // Script de inicialização (user data)
    userData := `#!/bin/bash
apt-get update
apt-get install -y golang-go
# ... restante do setup
`
    
    userDataEncoded := base64.StdEncoding.EncodeToString([]byte(userData))
    
    input := &ec2.RunInstancesInput{
        ImageId:      aws.String("ami-0c02fb55956c7d316"), // Amazon Linux 2
        InstanceType: types.InstanceTypeT3Micro,
        MinCount:     aws.Int32(1),
        MaxCount:     aws.Int32(1),
        KeyName:      aws.String("minha-chave-ssh"),
        UserData:     aws.String(userDataEncoded),
        SecurityGroupIds: []string{"sg-xxxxxxxxxxxx"},
        SubnetId:     aws.String("subnet-xxxxxxxxxxxx"),
        TagSpecifications: []types.TagSpecification{
            {
                ResourceType: types.ResourceTypeInstance,
                Tags: []types.Tag{
                    {Key: aws.String("Name"), Value: aws.String("servidor-go")},
                    {Key: aws.String("Ambiente"), Value: aws.String("producao")},
                },
            },
        },
    }
    
    result, err := client.RunInstances(ctx, input)
    if err != nil {
        return fmt.Errorf("falha ao criar instância: %w", err)
    }
    
    fmt.Printf("Instância criada: %s\n", *result.Instances[0].InstanceId)
    return nil
}

func main() {
    ctx := context.Background()
    
    cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("sa-east-1"))
    if err != nil {
        log.Fatal(err)
    }
    
    client := ec2.NewFromConfig(cfg)
    
    if err := criarInstanciaEC2(ctx, client); err != nil {
        log.Fatal(err)
    }
}
```

## AWS Lambda: Serverless com Go

Lambda é o serviço serverless da AWS, ideal para funções que respondem a eventos. O Go tem cold starts extremamente rápidos, tornando-o excelente para Lambda.

### handler.go - Estrutura Básica

```go
package main

import (
    "context"
    "encoding/json"
    "log"
    
    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
)

// Request representa o payload de entrada
type Request struct {
    Name string `json:"name"`
}

// Response representa a resposta
type Response struct {
    StatusCode int    `json:"statusCode"`
    Message    string `json:"message"`
}

func HandleRequest(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    var req Request
    
    if err := json.Unmarshal([]byte(request.Body), &req); err != nil {
        return events.APIGatewayProxyResponse{
            StatusCode: 400,
            Body:       `{"error": "JSON inválido"}`,
        }, nil
    }
    
    if req.Name == "" {
        req.Name = "Mundo"
    }
    
    response := Response{
        StatusCode: 200,
        Message:    "Olá, " + req.Name + "!",
    }
    
    body, _ := json.Marshal(response)
    
    return events.APIGatewayProxyResponse{
        StatusCode: 200,
        Body:       string(body),
        Headers: map[string]string{
            "Content-Type": "application/json",
        },
    }, nil
}

func main() {
    lambda.Start(HandleRequest)
}
```

### Build e Deploy via CLI

```bash
# Build para Lambda (Linux + ARM64 = melhor performance/custo)
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go build -o bootstrap -tags lambda.norpc .

# Compacta para upload
zip function.zip bootstrap

# Deploy via AWS CLI
aws lambda create-function \
    --function-name minha-funcao-go \
    --runtime provided.al2 \
    --handler bootstrap \
    --architectures arm64 \
    --role arn:aws:iam:: conta:role/minha-role-lambda \
    --zip-file fileb://function.zip

# Atualiza função existente
aws lambda update-function-code \
    --function-name minha-funcao-go \
    --zip-file fileb://function.zip
```

### Lambda com S3 Trigger

```go
package main

import (
    "context"
    "fmt"
    "log"
    
    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func handler(ctx context.Context, s3Event events.S3Event) error {
    cfg, err := config.LoadDefaultConfig(ctx)
    if err != nil {
        return err
    }
    
    s3Client := s3.NewFromConfig(cfg)
    
    for _, record := range s3Event.Records {
        bucket := record.S3.Bucket.Name
        key := record.S3.Object.Key
        
        log.Printf("Processando arquivo: s3://%s/%s", bucket, key)
        
        // Lógica de processamento aqui
        // Ex: thumbnail de imagem, parsing de CSV, etc.
        
        resp, err := s3Client.GetObject(ctx, &s3.GetObjectInput{
            Bucket: &bucket,
            Key:    &key,
        })
        if err != nil {
            return fmt.Errorf("falha ao ler objeto: %w", err)
        }
        defer resp.Body.Close()
        
        // Processa o arquivo...
        log.Printf("Tamanho do arquivo: %d bytes", resp.ContentLength)
    }
    
    return nil
}

func main() {
    lambda.Start(handler)
}
```

### Otimizando Cold Starts

Para minimizar o cold start em Lambda:

```go
package main

import (
    "context"
    "sync"
    
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb"
)

// Cliente singleton para reutilização entre invocações
var (
    dynamoClient *dynamodb.Client
    once         sync.Once
)

func getDynamoClient() *dynamodb.Client {
    once.Do(func() {
        cfg, _ := config.LoadDefaultConfig(context.Background())
        dynamoClient = dynamodb.NewFromConfig(cfg)
    })
    return dynamoClient
}

// init() roda uma vez no cold start
func init() {
    // Pré-inicializa conexões
    _ = getDynamoClient()
}

func handler(ctx context.Context, event interface{}) error {
    client := getDynamoClient()
    // Usa cliente já inicializado...
}
```

## Integração com S3: Armazenamento de Objetos

S3 (Simple Storage Service) é o serviço de armazenamento de objetos. Ideal para arquivos, backups, e assets estáticos.

### Operações Básicas

```go
package main

import (
    "context"
    "fmt"
    "io"
    "os"
    
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

type S3Service struct {
    client *s3.Client
    bucket string
}

func NewS3Service(ctx context.Context, bucket string) (*S3Service, error) {
    cfg, err := config.LoadDefaultConfig(ctx)
    if err != nil {
        return nil, err
    }
    
    return &S3Service{
        client: s3.NewFromConfig(cfg),
        bucket: bucket,
    }, nil
}

// Upload de arquivo
func (s *S3Service) Upload(ctx context.Context, key string, body io.Reader) error {
    _, err := s.client.PutObject(ctx, &s3.PutObjectInput{
        Bucket:      aws.String(s.bucket),
        Key:         aws.String(key),
        Body:        body,
        ContentType: aws.String("application/octet-stream"),
    })
    return err
}

// Download de arquivo
func (s *S3Service) Download(ctx context.Context, key string, dest io.Writer) error {
    result, err := s.client.GetObject(ctx, &s3.GetObjectInput{
        Bucket: aws.String(s.bucket),
        Key:    aws.String(key),
    })
    if err != nil {
        return err
    }
    defer result.Body.Close()
    
    _, err = io.Copy(dest, result.Body)
    return err
}

// Gerar URL pré-assinada (temporária)
func (s *S3Service) GetPresignedURL(ctx context.Context, key string, expireMinutes int) (string, error) {
    presignClient := s3.NewPresignClient(s.client)
    
    req, err := presignClient.PresignGetObject(ctx, &s3.GetObjectInput{
        Bucket: aws.String(s.bucket),
        Key:    aws.String(key),
    }, s3.WithPresignExpires(time.Duration(expireMinutes)*time.Minute))
    
    return req.URL, err
}

// Listar objetos
func (s *S3Service) ListObjects(ctx context.Context, prefix string) ([]string, error) {
    var keys []string
    
    paginator := s3.NewListObjectsV2Paginator(s.client, &s3.ListObjectsV2Input{
        Bucket: aws.String(s.bucket),
        Prefix: aws.String(prefix),
    })
    
    for paginator.HasMorePages() {
        page, err := paginator.NextPage(ctx)
        if err != nil {
            return nil, err
        }
        
        for _, obj := range page.Contents {
            keys = append(keys, *obj.Key)
        }
    }
    
    return keys, nil
}

func main() {
    ctx := context.Background()
    
    service, err := NewS3Service(ctx, "meu-bucket-producao")
    if err != nil {
        panic(err)
    }
    
    // Upload exemplo
    file, _ := os.Open("documento.pdf")
    defer file.Close()
    
    err = service.Upload(ctx, "uploads/documento.pdf", file)
    if err != nil {
        panic(err)
    }
    
    fmt.Println("Upload concluído!")
}
```

## RDS e DynamoDB: Conexão com Bancos de Dados

### Conectando ao RDS (PostgreSQL/MySQL)

```go
package main

import (
    "database/sql"
    "fmt"
    "log"
    
    _ "github.com/lib/pq" // PostgreSQL driver
)

func conectarRDS() (*sql.DB, error) {
    // É importante usar SSL em produção
    // Baixe o certificado: https://truststore.pki.rds.amazonaws.com/
    connStr := "host=banco.xxxxx.sa-east-1.rds.amazonaws.com " +
        "port=5432 " +
        "user=admin " +
        "password=senha-secreta " +
        "dbname=meubanco " +
        "sslmode=require"
    
    db, err := sql.Open("postgres", connStr)
    if err != nil {
        return nil, err
    }
    
    // Testa conexão
    if err := db.Ping(); err != nil {
        return nil, err
    }
    
    // Configurações de pool
    db.SetMaxOpenConns(25)
    db.SetMaxIdleConns(10)
    
    return db, nil
}
```

### DynamoDB com Go

```go
package main

import (
    "context"
    "fmt"
    
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb"
    "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
)

type Usuario struct {
    ID    string `dynamodbav:"id"`
    Nome  string `dynamodbav:"nome"`
    Email string `dynamodbav:"email"`
    Idade int    `dynamodbav:"idade"`
}

type DynamoService struct {
    client    *dynamodb.Client
    tableName string
}

func NewDynamoService(ctx context.Context, tableName string) (*DynamoService, error) {
    cfg, err := config.LoadDefaultConfig(ctx)
    if err != nil {
        return nil, err
    }
    
    return &DynamoService{
        client:    dynamodb.NewFromConfig(cfg),
        tableName: tableName,
    }, nil
}

func (s *DynamoService) PutUsuario(ctx context.Context, u Usuario) error {
    item, err := attributevalue.MarshalMap(u)
    if err != nil {
        return err
    }
    
    _, err = s.client.PutItem(ctx, &dynamodb.PutItemInput{
        TableName: aws.String(s.tableName),
        Item:      item,
    })
    
    return err
}

func (s *DynamoService) GetUsuario(ctx context.Context, id string) (*Usuario, error) {
    result, err := s.client.GetItem(ctx, &dynamodb.GetItemInput{
        TableName: aws.String(s.tableName),
        Key: map[string]types.AttributeValue{
            "id": &types.AttributeValueMemberS{Value: id},
        },
    })
    if err != nil {
        return nil, err
    }
    
    if result.Item == nil {
        return nil, fmt.Errorf("usuário não encontrado")
    }
    
    var usuario Usuario
    err = attributevalue.UnmarshalMap(result.Item, &usuario)
    return &usuario, err
}

func main() {
    ctx := context.Background()
    
    service, err := NewDynamoService(ctx, "Usuarios")
    if err != nil {
        panic(err)
    }
    
    usuario := Usuario{
        ID:    "user-123",
        Nome:  "João Silva",
        Email: "joao@exemplo.com",
        Idade: 30,
    }
    
    if err := service.PutUsuario(ctx, usuario); err != nil {
        panic(err)
    }
    
    fmt.Println("Usuário salvo com sucesso!")
}
```

## Melhores Práticas para Deploy em Produção

### 1. Health Checks e Graceful Shutdown

```go
package main

import (
    "context"
    "net/http"
    "os"
    "os/signal"
    "syscall"
    "time"
    
    "github.com/gorilla/mux"
)

func main() {
    router := mux.NewRouter()
    
    // Health check para Load Balancer
    router.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
        // Verifica conexões de banco, etc.
        w.WriteHeader(http.StatusOK)
        w.Write([]byte(`{"status": "ok"}`))
    }).Methods("GET")
    
    srv := &http.Server{
        Addr:    ":8080",
        Handler: router,
    }
    
    // Graceful shutdown
    stop := make(chan os.Signal, 1)
    signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
    
    go func() {
        if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
            log.Fatalf("Erro no servidor: %v", err)
        }
    }()
    
    <-stop
    
    ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
    defer cancel()
    
    if err := srv.Shutdown(ctx); err != nil {
        log.Printf("Erro no shutdown: %v", err)
    }
}
```

### 2. Observabilidade (CloudWatch)

```go
import "github.com/aws/aws-sdk-go-v2/service/cloudwatch"

func emitirMétrica(ctx context.Context, client *cloudwatch.Client, valor float64) {
    _, err := client.PutMetricData(ctx, &cloudwatch.PutMetricDataInput{
        Namespace: aws.String("MinhaApp/Go"),
        MetricData: []types.MetricDatum{
            {
                MetricName: aws.String("RequisicoesPorSegundo"),
                Value:      aws.Float64(valor),
                Unit:       types.StandardUnitCount,
                Dimensions: []types.Dimension{
                    {
                        Name:  aws.String("Ambiente"),
                        Value: aws.String("producao"),
                    },
                },
            },
        },
    })
}
```

### 3. Segurança

- **Nunca commit credenciais**: Use AWS Secrets Manager ou IAM Roles
- **Criptografia em trânsito**: Sempre use HTTPS
- **Security Groups**: Restrinja acesso apenas ao necessário
- **Atualizações regulares**: Mantenha a AMI e pacotes atualizados

```go
// Exemplo: Ler segredo do Secrets Manager
func getSecret(ctx context.Context, secretName string) (string, error) {
    cfg, _ := config.LoadDefaultConfig(ctx)
    client := secretsmanager.NewFromConfig(cfg)
    
    result, err := client.GetSecretValue(ctx, &secretsmanager.GetSecretValueInput{
        SecretId: aws.String(secretName),
    })
    if err != nil {
        return "", err
    }
    
    return *result.SecretString, nil
}
```

## Pipeline CI/CD com GitHub Actions

```yaml
# .github/workflows/deploy-aws.yml
name: Deploy to AWS

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Go
      uses: actions/setup-go@v4
      with:
        go-version: '1.21'
    
    - name: Run tests
      run: go test -v ./...
    
    - name: Build
      run: |
        GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o app .
    
    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v4
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: sa-east-1
    
    - name: Deploy to S3 (para EC2 pull)
      run: |
        aws s3 cp app s3://meu-bucket-deploy/app-${{ github.sha }}
    
    - name: Deploy to Lambda (se for função Lambda)
      run: |
        zip function.zip app
        aws lambda update-function-code \
          --function-name minha-funcao \
          --zip-file fileb://function.zip
```

## Custos e Otimização

### EC2 vs Lambda: Quando usar cada um?

| Cenário | Melhor Opção | Por quê? |
|---------|--------------|----------|
| API com tráfego constante | EC2 (ou ECS/EKS) | Mais barato para uso contínuo |
| Processamento de filas | Lambda | Escala automaticamente |
| Batch jobs agendados | Lambda + CloudWatch Events | Paga apenas pelo tempo de execução |
| Aplicação complexa | ECS/Fargate | Melhor controle sem gerenciar servidores |

### Dicas de economia:

1. **Instâncias Spot**: Até 90% mais barato para cargas tolerantes a interrupções
2. **Reserved Instances**: Compromisso de 1-3 anos para desconto de até 75%
3. **Lambda**: Configure memória corretamente (mais memória = mais CPU)
4. **S3**: Use lifecycle policies para arquivar dados antigos

## Exemplo Completo: Aplicação RESTful

Aqui está uma aplicação completa que combina vários serviços AWS:

```go
// cmd/api/main.go
package main

import (
    "log"
    "net/http"
    
    "github.com/gorilla/mux"
)

type Server struct {
    db    *sql.DB
    s3    *S3Service
    cache *CacheService
}

func main() {
    ctx := context.Background()
    
    // Inicializa serviços
    db, err := conectarRDS()
    if err != nil {
        log.Fatal(err)
    }
    
    s3, err := NewS3Service(ctx, os.Getenv("S3_BUCKET"))
    if err != nil {
        log.Fatal(err)
    }
    
    server := &Server{db: db, s3: s3}
    
    // Rotas
    router := mux.NewRouter()
    router.HandleFunc("/health", server.healthCheck).Methods("GET")
    router.HandleFunc("/users", server.createUser).Methods("POST")
    router.HandleFunc("/users/{id}", server.getUser).Methods("GET")
    router.HandleFunc("/upload", server.uploadFile).Methods("POST")
    
    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }
    
    log.Printf("Servidor iniciando na porta %s", port)
    log.Fatal(http.ListenAndServe(":"+port, router))
}
```

## Conclusão

A combinação de Go e AWS oferece uma plataforma poderosa para aplicações em nuvem. A simplicidade do Go, com seu binário único e startup rápido, casa perfeitamente com a flexibilidade dos serviços AWS.

### Próximos Passos

1. Experimente o **AWS Free Tier** (gratuito por 12 meses)
2. Comece com **Lambda** para experimentar sem custos fixos
3. Use **Elastic Beanstalk** para deployments simples de aplicações web
4. Explore **AWS CDK** para infraestrutura como código
5. Monitore seus custos no **AWS Billing Dashboard**

### Recursos Adicionais

- [AWS SDK for Go v2 Documentation](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2)
- [AWS Go Builder's Library](https://aws.amazon.com/developer/language/go/)
- [Well-Architected Framework](https://aws.amazon.com/architecture/well-architected/)
- [Go em Kubernetes](/tutoriais/go-kubernetes/) - Aprenda a orquestrar seus containers
- [Go e Docker](/tutoriais/go-docker-container/) - Containerização de aplicações Go

---

*Tem dúvidas sobre deploy na AWS? A AWS oferece créditos gratuitos para startups através do programa AWS Activate.*
