# Boas Práticas - Terraform Provider

Aprenda as melhores práticas para usar o Azion Terraform Provider de forma eficiente e segura.

---

## Organização do Código

### Estrutura de Diretórios

Organize seus arquivos Terraform de forma lógica:

```
terraform/
├── main.tf              # Provider e configurações principais
├── variables.tf         # Variáveis de entrada
├── outputs.tf           # Outputs
├── providers.tf         # Configuração de providers
├── backend.tf           # Configuração de backend
├── modules/
│   ├── workload/
│   │   ├── main.tf
│   │   ├── variables.tf
│   │   └── outputs.tf
│   └── application/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
└── environments/
    ├── dev/
    │   ├── main.tf
    │   └── terraform.tfvars
    ├── staging/
    └── prod/
```

### Nomenclatura

Use nomes descritivos e consistentes:

```hcl
# Bom
resource "azion_workload" "api_gateway" {
  name = "api-gateway-prod"
}

# Evite
resource "azion_workload" "w1" {
  name = "w1"
}
```

---

## Gerenciamento de Estado

### Backend Remoto

Sempre use um backend remoto para armazenar o estado:

```hcl
# backend.tf
terraform {
  backend "s3" {
    bucket         = "meu-terraform-state"
    key            = "azion/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"
  }
}
```

### Locking

Use locking para evitar conflitos:

```hcl
# Com S3 + DynamoDB
terraform {
  backend "s3" {
    bucket         = "meu-terraform-state"
    key            = "azion/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"
  }
}
```

---

## Segurança

### Variáveis Sensíveis

Marque variáveis sensíveis como `sensitive`:

```hcl
variable "api_token" {
  type        = string
  description = "Personal Token da Azion"
  sensitive   = true
}
```

### Não Commite Segredos

Adicione ao `.gitignore`:

```gitignore
# Terraform
*.tfstate
*.tfstate.backup
*.tfvars
.terraform/
terraform.tfvars
secrets.tf
```

### Use Variáveis de Ambiente

```bash
export TF_VAR_api_token="seu-token"
```

---

## Modularização

### Criando Módulos

Crie módulos reutilizáveis:

```hcl
# modules/workload/main.tf
variable "name" {
  type = string
}

variable "environment" {
  type = string
}

resource "azion_workload" "this" {
  name = "${var.name}-${var.environment}"
}

output "workload_id" {
  value = azion_workload.this.id
}
```

### Usando Módulos

```hcl
# main.tf
module "api_workload" {
  source      = "./modules/workload"
  name        = "api"
  environment = "prod"
}
```

---

## CI/CD

### Pipeline Básico

Exemplo com GitHub Actions:

```yaml
# .github/workflows/terraform.yml
name: Terraform

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - uses: hashicorp/setup-terraform@v2
      
      - name: Terraform Init
        run: terraform init
        
      - name: Terraform Plan
        run: terraform plan
        env:
          AZION_API_TOKEN: ${{ secrets.AZION_API_TOKEN }}
        
      - name: Terraform Apply
        if: github.ref == 'refs/heads/main'
        run: terraform apply -auto-approve
        env:
          AZION_API_TOKEN: ${{ secrets.AZION_API_TOKEN }}
```

---

## Versionamento

### Fixe Versões

Sempre fixe a versão do provider:

```hcl
terraform {
  required_providers {
    azion = {
      source  = "aziontech/azion"
      version = "2.0.0"  # Fixe a versão
    }
  }
}
```

### Use `.terraform-version`

Para projetos com múltiplas versões:

```
1.41.0
```

---

## Outputs

### Exporte IDs Importantes

```hcl
output "workload_id" {
  description = "ID do workload criado"
  value       = azion_workload.main.id
}

output "application_id" {
  description = "ID da aplicação criada"
  value       = azion_application_main_setting.main.id
}
```

### Use Outputs em Módulos

```hcl
# modules/application/outputs.tf
output "application_id" {
  value = azion_application_main_setting.this.id
}

output "application_name" {
  value = azion_application_main_setting.this.name
}
```

---

## Dependências

### Depends_On

Use `depends_on` para dependências implícitas:

```hcl
resource "azion_workload" "main" {
  name = "meu-workload"
}

resource "azion_workload_deployment" "main" {
  workload_id = azion_workload.main.id
  depends_on   = [azion_workload.main]
}
```

### Referências Implícitas

Prefira referências diretas:

```hcl
# Bom
resource "azion_application_rule_engine" "example" {
  application_id = azion_application_main_setting.example.id
}

# Evite
resource "azion_application_rule_engine" "example" {
  application_id = "12345"  # Hardcoded
}
```

---

## Documentação

### Comente Seu Código

```hcl
# Workload para a API principal
# Este workload gerencia a API de produção
resource "azion_workload" "api" {
  name = "api-prod"
}
```

### README

Crie um `README.md` para cada módulo:

```markdown
# Módulo Workload

## Uso

\`\`\`hcl
module "workload" {
  source = "./modules/workload"
  name   = "api"
}
\`\`\`

## Inputs

| Nome | Descrição | Tipo | Padrão |
|------|-----------|------|--------|
| name | Nome do workload | string | n/a |

## Outputs

| Nome | Descrição |
|------|-----------|
| workload_id | ID do workload |
```

---