Может ли terraform дублировать содержимое ведра s3? - PullRequest
0 голосов
/ 08 июля 2020

Я использую terraform для управления aws средами нашего приложения. В средах есть ведра s3 для разных вещей. И при настройке новой среды я просто хочу скопировать сегменты из базового исходного сегмента или из существующей среды.

Но я не могу найти ничего, что могло бы предоставить копию. Интерфейс AWS позволяет дублировать настройку при создании (что мне не нужно), но не объекты, так что это может не быть чем-то, что terraform может делать напрямую.

Если да, то как насчет косвенного?

Ответы [ 2 ]

1 голос
/ 09 июля 2020

В общем, провайдеры Terraform отражают операции, которые изначально поддерживаются базовыми API, но в некоторых случаях мы можем использовать различные типы ресурсов Terraform вместе для достижения функциональности, которой не хватает базовому провайдеру.

Я считаю, что есть нет собственной операции S3 для массового копирования объектов из одной корзины в другую, поэтому для решения этой проблемы с помощью Terraform требуется разложить проблему на более мелкие шаги, которые, как я думаю, в этом случае будут следующими:

  • Список всех объектов в исходном сегменте
  • Объявить один объект в новом сегменте для каждого объекта в исходном сегменте.

* Поставщик 1036 * в принципе может выполнять все три из этих операций: у него есть управляемые типы ресурсов как для сегментов, так и для объектов сегментов, и у него есть источник данных aws_s3_bucket_objects, который может перечислять некоторые или все объекты в ведро.

Мы можем объединить эти части вместе в конфигурации Terraform рацион примерно такой:

resource "aws_s3_bucket" "target" {
  bucket = "copy-example-target"
}

data "aws_s3_bucket_objects" "source" {
  bucket = "copy-example-source"
}

data "aws_s3_bucket_object" "source" {
  for_each = toset(data.aws_s3_bucket_objects.source.keys)

  bucket = data.aws_s3_bucket_objects.source.bucket
  key    = each.key
}

resource "aws_s3_bucket_object" "target" {
  for_each = aws_s3_bucket_object.source

  bucket  = aws_s3_bucket.target.bucket
  key     = each.key
  content = each.value.body
}

С учетом сказанного, Terraform, вероятно, не лучший инструмент для этой ситуации по следующим причинам:

  • Приведенная выше конфигурация заставит Terraform читать все объекты в корзине в память, что отнимет много времени и потребует много ОЗУ для больших корзин, а затем в конечном итоге все они будут сохранены в состоянии Terraform, что сделало бы само состояние очень большим.
  • Поскольку источник данных aws_s3_bucket_object предназначен в основном для извлечения небольших текстовых объектов, вышеуказанное будет работать, только если все в корзине соответствует ограничениям, описанным в документации aws_s3_bucket_object : все объекты должны имеют текстовые типы MIME, и все они должны содержать текст в кодировке UTF-8.

В этом случае я бы предпочел использовать специализированный инструмент для работы, который предназначен для использования всех функции S3 API, чтобы сделать копию максимально эффективной, например, потоковая передача списка объектов nd потоковая передача содержимого каждого объекта по частям, чтобы избежать необходимости хранить все данные в памяти одновременно. Один из таких инструментов находится в самом AWS CLI в виде команды aws s3 cp с параметром --recursive.

1 голос
/ 08 июля 2020

Нет ресурса, позволяющего копировать объекты из одной корзины S3 в другую. Если вы хотите включить это в свою настройку Terraform, вам нужно будет использовать local-exe c Provisioner.

Он должен будет выполнить команду ниже, с поддержкой AWS CLI для запуска aws s3 cp.

resource "null_resource" "s3_objects" {
  provisioner "local-exec" {
    command = "aws s3 cp s3://bucket1 s3://bucket2 --recursive"
  }
}

Для этого для запуска на локальном сервере должен быть установлен AWS CLI с ролью (или действительными учетными данными) для включения копии.

...