【问题标题】:Can terraform duplicate the content of an s3 bucket?terraform 可以复制 s3 存储桶的内容吗?
【发布时间】:2020-10-29 06:20:10
【问题描述】:

我正在使用 terraform 来管理我们应用程序的 aws 环境。环境具有用于各种事物的 s3 存储桶。在设置新环境时,我只想从基本源存储桶或现有环境中复制存储桶。

但我找不到任何可以提供副本的东西。 AWS 界面允许您在创建时复制设置(我不需要),但不能复制对象,因此它可能不是 terraform 可以直接执行的操作。

如果是,那么间接呢?

【问题讨论】:

  • 只是为了确认请求通过 Terraform 将 S3 存储桶的内容复制到新的 S3 存储桶?
  • 是的,总的来说是创建一个新的bucket,并且与现有的bucket具有相同的内容。如果这意味着首先创建新存储桶,然后以某种方式将源存储桶的内容复制到新存储桶中,那就这样吧。

标签: amazon-web-services amazon-s3 terraform


【解决方案1】:

没有资源可以将对象从一个 S3 存储桶复制到另一个存储桶。如果您想将其包含在您的 Terraform 设置中,则需要使用 local-exec 供应商。

它需要执行下面的命令,并支持 AWS CLI 运行aws s3 cp

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

为此,本地服务器需要AWS CLI installed 和角色(或有效凭据)才能启用副本。

【讨论】:

  • 有趣。我想我可以做到这一点。在本地它会很容易......困难的部分将是让它在 teamcity 内工作...... :) 但这完全是一个内部问题。谢谢。
  • 没问题,很高兴我能帮上忙 :)
  • 这可能不再准确。我今天注意到了这一点:registry.terraform.io/providers/hashicorp/aws/latest/docs/… - 它似乎通过 TF 进行对象复制,但遵循 TF 的“做事方式”,因为它仅在需要复制时才会复制。跨度>
  • 也许尽管考虑到这是一个逐个对象的副本,而不是存储桶的全部内容
【解决方案2】:

一般来说,Terraform 提供者反映了底层 API 原生支持的操作,但在某些情况下,我们可以一起使用各种 Terraform 资源类型来实现底层提供者缺乏的功能。

我相信没有用于将对象从一个存储桶批量复制到另一个存储桶的原生 S3 操作,因此使用 Terraform 解决此问题需要将问题分解为更小的步骤,我认为在这种情况下应该是:

  • 声明一个新的桶,目标
  • 列出源存储桶中的所有对象
  • 为源存储桶中的每个对象声明一个新存储桶中的对象。

原则上,AWS 提供商可以执行所有这三种操作:它具有用于存储桶和存储桶对象的托管资源类型,并且它具有可以枚举存储桶中的部分或全部对象的数据源 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 将存储桶中的所有对象读取到内存中,这将非常耗时,并且会为较大的存储桶使用大量 RAM,然后最终将所有对象存储在 Terraform 状态,这会使国家本身非常大。
  • 因为aws_s3_bucket_object 数据源主要用于检索基于文本的小型对象,所以只有当存储桶中的所有内容都满足the aws_s3_bucket_object documentation 中描述的限制时,上述方法才有效:对象都必须具有指示文本的 MIME 类型并且它们都必须包含 UTF-8 编码的文本。

在这种情况下,我更愿意使用专门的工具来完成这项工作,该工具旨在利用 S3 API 的所有功能来尽可能高效地复制,例如流式传输对象列表和流式传输块中每个对象的内容,以避免需要一次将所有数据保存在内存中。 AWS CLI 本身就是这样一种工具,其形式为带有--recursive 选项的aws s3 cp 命令。

【讨论】:

  • 感谢您提供的信息... 是的,我原以为这样的事情是可能的。但担心这也会花费很多,因为文件必须实际移动到正在运行的机器上。我希望 cp 的 AWS cli 命令实际上不会将文件带到正在运行的主机上。但是我在谷歌搜索时找不到任何 100% 的证据。也就是说,我什至没有考虑到文件内容最终会出现在 statefile 中。其中一个存储桶很大...... cli 复制需要几个小时。
猜你喜欢
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-12
  • 2019-10-30
  • 2021-04-02
  • 2023-03-26
相关资源
最近更新 更多