Terraform: копирование файла на EC2 с помощью file provisioner

Что вы узнаете
- Как настроить file provisioner для копирования файла на EC2.
- Какие аргументы используются в блоке file и connection.
- Ограничения и альтернативы — когда не стоит использовать provisioners.
- Чек-лист для DevOps/SRE, критерии приёмки и распространённые ошибки.
Введение
Когда вы создаёте EC2 через Terraform, иногда нужно, чтобы определённый файл оказался на машине сразу после старта. Пример: шаблон конфигурации виртуального хоста Apache, который затем используется для генерации 2 конфигураций. Для таких задач существует file provisioner — он пересылает файлы с машины, где запускается Terraform, на удалённую целевую систему.
Важно: официальные рекомендации Terraform рассматривают provisioners как крайний вариант и советуют использовать более надёжные и масштабируемые подходы, когда это возможно. Ниже мы объясним почему и предложим альтернативы.
Краткое пояснение терминов
- Provisioner: механизм Terraform для выполнения действий на машине после её создания (копирование файлов, запуск скриптов и т. п.).
- connection: блок в ресурсе, который указывает, как Terraform подключается к целевой системе (ssh или winrm).
Предварительные требования
- Знание базового Terraform.
- Установленные Terraform и AWS CLI на локальной машине.
- AWS CLI настроен для доступа к вашему аккаунту AWS.
Практическая часть: пример с file provisioner
Ниже приведён пошаговый пример, в котором мы создаём локальный файл и копируем его на EC2 при создании инстанса.
Шаг 1. Создайте файл, который хотите передать на удалённую систему (в каталоге проекта Terraform):
$ nano dummy.txtДобавьте содержимое в файл:
$ echo "Our dummy file" > dummy.txtШаг 2. Создайте файл конфигурации Terraform, например instance.tf:
$ nano instance.tfВставьте в него следующий пример (замените значения на свои):
provider "aws" {
region ="us-east-1"
}
resource "aws_instance" "webserver" {
ami ="ami-id-you-want-to-use"
instance_type = "t2.micro"
key_name = "Name-of-your- EC2-keypair"
vpc_security_group_ids = ["Use-an-existing-SG"]
associate_public_ip_address = true
provisioner "file" {
source = "dummy.txt"
destination = "/home/ubuntu/file1.txt"
connection {
type = "ssh"
user = "ubuntu"
private_key = "${file("Path-to-EC2-keyPair-on-Local-system.pem")}"
host = "${self.public_ip}"
}
}
tags = {
Name = "FileProvisionerDemo"
}
}Пояснения к ключевым аргументам:
- source: абсолютный или относительный путь к файлу/директории на локальной машине (относительно директории проекта Terraform).
- destination: абсолютный путь на целевой системе.
- connection: как подключаться к создаваемому ресурсу (ssh/winrm).
- type: тип подключения — “ssh” или “winrm”.
- user: пользователь для SSH-подключения (например, ubuntu для образов Ubuntu).
- private_key: содержимое приватного ключа (обычно через функцию file()).
- host: адрес целевой машины — в примере мы используем self.public_ip, где self — объект родительского ресурса.
File provisioner также поддерживает дополнительные опции (certificate, agent, host_key и т. п.).
Шаг 3. Инициализируйте директорию:
$ terraform init
Проверьте синтаксис и конфигурацию:
$ terraform validateШаг 4. Просмотрите план и примените изменения:
$ terraform plan
$ terraform applyПримерный фрагмент вывода при создании ресурса:
Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_instance.webserver will be created
+ resource "aws_instance" "webserver" Шаг 5. Инстанс создаётся; после завершения Terraform попытaется подключиться по SSH и скопировать файл. На стороне AWS можно следить за созданием в консоли EC2.

Когда инстанс доступен, подключитесь по SSH и проверьте наличие файла:

Когда provisioner не подходит — типичные ограничения и ошибки
- Зависимость от порядка: provisioner выполняется после создания ресурса. Если сеть/SSH ещё не готовы — операция завершится неудачей.
- Идемпотентность: provisioner может нарушать идемпотентность конфигурации (повторное применение может повторно копировать или перезаписывать файлы).
- Масштабируемость: при множестве инстансов управление через provisioners менее предсказуемо.
- Безопасность: хранение приватных ключей и чувствительных файлов рядом с проектом требует аккуратной практики.
Важно: Terraform официально советует применять provisioners только когда другие варианты невозможны.
Альтернативные подходы (рекомендуется чаще использовать вместо provisioners)
- cloud-init / user_data: передать скрипт в userdata, который выполнится при первом запуске инстанса. Надёжнее на старте и не требует прямого SSH от Terraform.
- Bake AMI (Packer): подготовить образ с уже встроенными файлами/зависимостями. Хорошая практика для production.
- S3 + bootstrap: положить файлы в S3 и при старте скачивать их с помощью userdata.
- Конфигурационные инструменты: Ansible/Chef/Puppet/Salt — для пост-продакшн-прослойки и управления конфигурациями.
Каждый вариант имеет свои преимущества: user_data прост для одноразовой инициализации, Packer даёт контролируемые образы, S3 + userdata удобен для передачи больших файлов.
Ментальные модели и эвристики
- Правило «инициализация на старте»: если файл нужен только при первом boot — используйте user_data или cloud-init.
- Правило «образа и воспроизводимости»: если нужна стабильность и быстрое масштабирование — пекайте AMI.
- Правило «конфигурационного управления»: если инфраструктура динамичная и файл может меняться — используйте Ansible/CM.
Роль‑ориентированный чек‑лист (DevOps / SRE / Security)
Для DevOps:
- Убедиться, что ключи доступа и ssh-файлы не закоммичены.
- Протестировать terraform apply в тестовой среде.
Для SRE:
- Проверить идемпотентность конфигурации при повторных apply.
- Подготовить мониторинг и логи для сценариев, когда provisioner не может подключиться.
Для Security:
- Приватные ключи хранить в защищённом хранилище (vault, secret manager).
- Минимизировать права security group — открыть SSH только от доверенных IP/CI runner.
Критерии приёмки
- Файл присутствует в указанном destination после успешного terraform apply.
- Провайдер не выводит ошибок в ходе копирования.
- Скрипты или сервисы, зависящие от файла, запускаются и работают корректно.
- Нет приватных ключей в репозитории (проверка git history).
Отладка: распространённые ошибки и как их решать
- SSH timeout / connection refused: проверьте security group, публичный IP, правильность пользователя и приватного ключа.
- Permission denied при записи в destination: используйте временную директорию пользователя (например, /home/ubuntu) и потом корректный mv/chown через remote-exec или userdata.
- Файл не доступен после reboot: убедитесь, что Вы не копируете в tmp-папки, очищаемые системой.
Полезная команда для локальной проверки ключа:
$ ssh -i Path-to-EC2-keyPair-on-Local-system.pem ubuntu@Факт‑бокс — ключевые пункты
- Поддерживаемые типы connection: ssh и winrm.
- file provisioner копирует файлы с хоста, где запускается Terraform, на целевую систему.
- Terraform рекомендует альтернативы: user_data, Packer, S3 + bootstrap, CM-инструменты.
Примеры, когда file provisioner уместен
- Быстрая тестовая среда, где нужно поместить конфиг один раз.
- Демонстрационные проекты и PoC.
- Когда нет возможности модифицировать образ или передавать userdata.
Примеры, когда он не подходит
- Production-кластеры с автоскейлингом и быстрым развёртыванием.
- Случаи, где требуется строгая идемпотентность и версияция артефактов.
Рекомендуемые шаги для безопасного использования
- Не храните приватные ключи в репозитории.
- Используйте переменные и secret-manager для чувствительных данных.
- Логируйте операции и проверяйте состояние после apply.
- По возможности — используйте cloud-init или AMI.
Краткое резюме
File provisioner в Terraform — удобный инструмент для передачи файлов на только что созданный инстанс EC2. Однако он не универсален и часто уступает по надёжности и воспроизводимости подходам вроде user_data, baking AMI или использованию S3/CM. Используйте provisioners для быстрых задач и тестов, а для production предпочитайте более стабильные методы.
Важное: всегда тестируйте процесс в изолированной среде, следите за безопасностью приватных ключей и документируйте выбранный подход для команды.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента