Ответ
Terraform никогда не должен хранить секреты в коде или в plain-text состояниях. Вот основные и безопасные источники, которые я использую:
1. Переменные окружения (Environment Variables) - для локальной разработки:
# Используются автоматически для одноимённых параметров провайдера
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
# Для других провайдеров
export DIGITALOCEAN_TOKEN="..."
2. Динамические credentials через IAM-роли (лучшая практика для AWS):
- Для EC2/ECS/EKS: используется IAM Role, привязанная к инстансу.
- Для локальной разработки: используется AWS CLI/SSO или инструменты вроде
aws-vault.provider "aws" { region = "eu-west-1" # Никаких статических ключей! Credentials берутся из цепочки AWS SDK. }
3. Специализированные хранилища секретов (Secrets Managers):
# Пример с AWS Secrets Manager
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = "prod/postgres/master"
}
resource "aws_db_instance" "main" {
password = data.aws_secretsmanager_secret_version.db_password.secret_string
}
4. CI/CD Pipeline Variables (для автоматизации):
- Секреты инжектируются как переменные окружения в пайплайн (GitLab CI, GitHub Actions, Jenkins).
- В GitLab CI:
# .gitlab-ci.yml deploy: script: - export TF_VAR_db_password="$PROD_DB_PASSWORD" - terraform apply
5. Backend с шифрованием состояния (например, S3 + DynamoDB с KMS):
# backend.tf
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "prod/network.tfstate"
region = "eu-west-1"
encrypt = true # Шифрование на стороне S3
kms_key_id = "alias/terraform-state-key" # Доп. шифрование KMS
dynamodb_table = "terraform-locks"
}
}
Критичное правило: Файлы *.tfvars, содержащие секреты (например, secrets.tfvars), должны быть в .gitignore. Состояние (state file) всегда должно храниться в защищённом бэкенде с шифрованием.