Откуда Terraform берёт секреты (например, ключи доступа)?

«Откуда Terraform берёт секреты (например, ключи доступа)?» — вопрос из категории Terraform, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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) всегда должно храниться в защищённом бэкенде с шифрованием.