Шифруется ли state-файл в Terraform?

Ответ

Нет, локальный state-файл (terraform.tfstate) по умолчанию не шифруется. Он хранится в виде обычного JSON-файла, содержащего в открытом виде все ресурсы, их атрибуты, а иногда и чувствительные данные (пароли, приватные ключи, токены). Хранить его локально или в Git — серьезная угроза безопасности.

Как мы решаем эту проблему в продакшене:

  1. Используем удаленный бэкенд с шифрованием. Например, AWS S3 с включенным шифрованием на стороне сервера (SSE-S3 или SSE-KMS) и блокировкой состояния через DynamoDB.
    terraform {
      backend "s3" {
        bucket = "company-terraform-state-prod"
        key    = "network/terraform.tfstate"
        region = "eu-west-1"
        encrypt = true
        dynamodb_table = "terraform-state-lock"
      }
    }
  2. Никогда не коммитим state-файлы. Они добавлены в глобальный .gitignore.
  3. Управляем доступом. Доступ к бакету с state имеют только CI/CD пайплайны и инженеры через IAM-роли.
  4. Для чувствительных выходных данных используем механизм sensitive = true в output или внешние системы хранения секретов (HashiCorp Vault, AWS Secrets Manager).

Ответ 18+ 🔞

Бля, ну вот же классика, ёпта! Каждый раз одно и то же — люди берут Terraform, настраивают кучу ресурсов, а потом смотрят на этот самый terraform.tfstate и думают: «Ну файл и файл, чё бубнить-то». А потом у них в гите оказываются пароли от базы и ключи доступа, и начинается: «Ой, нас взломали!».

Так вот, слушай сюда, дружище. Этот самый terraform.tfstate — он по умолчанию не шифруется вообще нихуя. Это просто текстовый JSON-файл, в котором лежит всё, что ты наваял. И под «всё» я имею в виду не только названия серверов, а иногда и прямые пароли, приватные ключи, API-токены — весь этот компот. Хранить его просто на диске или, не дай бог, пихать в Git — это верх идиотизма, ядрёна вошь. Это как оставить ключи от квартиры под ковриком с запиской «заходите».

Так как же делать правильно, чтобы не было потом волнения ебать? Сейчас разжуем.

Правильный путь, он же единственный для продакшена:

  1. Забей на локальный state и используй удалённый бэкенд. Это основа основ. Берёшь, например, AWS S3, создаёшь там бакет специально для state-файлов и включаешь на нём шифрование (SSE-S3 или, что круче, SSE-KMS). А чтобы два человека одновременно не начали ломать инфраструктуру, прикручиваешь блокировку состояния через DynamoDB. Вот как это выглядит в коде:

    terraform {
      backend "s3" {
        bucket = "my-super-secure-tf-state-bucket"
        key    = "prod/network/terraform.tfstate"
        region = "eu-north-1"
        encrypt = true # Вот эта штука включает шифрование, без неё — пиши пропало
        dynamodb_table = "terraform-state-locking-table"
      }
    }

    После такой настройки твой state будет лежать в зашифрованном виде в облаке, и с ним сможет работать только тот, у кого есть нужные IAM-права. Никаких случайных сливов.

  2. .gitignore — твой лучший друг. Добавляешь *.tfstate и *.tfstate.* в глобальный .gitignore и забываешь, как страшный сон. Коммитить state-файлы — моветон уровня «пидарас шерстяной».

  3. Жёстко контролируй доступ. К бакету с state-файлами доступ должен быть только у CI/CD-системы (типа Jenkins или GitLab Runner) и у узкого круга инженеров через их IAM-роли. Никаких публичных чтений, блядь!

  4. Для особо чувствительных данных (пароли, токены) не надейся только на state. Используй в outputs параметр sensitive = true, чтобы Terraform не выплёвывал их в лог при каждом apply. А для хранения самих секретов лучше использовать специализированные системы вроде HashiCorp Vault или AWS Secrets Manager. Прятать пароль в переменную Terraform — это уже полумера.

Короче, суть в чём: доверия к локальному state-файлу — ноль ебать. Относись к нему как к критической уязвимости по умолчанию. Всё, что важно, должно быть в зашифрованном удалённом бэкенде с контролем доступа. И тогда спать будешь спокойно, а не просыпаться в холодном поту от мысли, что какой-то левый чувак теперь имеет доступ ко всей твоей инфраструктуре.