我需要为在s3变量中传递的每个data_uri设置aws data_uri访问点;这是为了提供一个跨帐户uri(s)。我只需要从这些data_uri中的每一个解析桶名,然后为每个桶创建资源。我该怎么做?
以下是我到目前为止所拥有的:
resource "aws_s3_access_point" "s3_access_point" {
count = var.create ? 1 : 0
for_each = var.inference
bucket = split("/", replace(each.value.image_uri, "s3://", ""))[0]
name = format("%s-%s", split("/", replace(each.value.image_uri, "s3://", ""))[0], "-access-point")
}变量如下所示:
{
"inference": [
{
"data_uri": "s3://my_bucket/model.tar.gz"
},
{
"data_uri": "s3://my_bucket_2/model.tar.gz"
},
{
"data_uri": "s3://my_bucket_3/model.tar.gz"
}
]
}发布于 2022-08-13 00:39:12
如果命名是一致的,我建议使用拆分。另外,您不能将计数和每一个混合使用;根据情况需要使用其中的一种。
注:这个答案是根据下面的评论重新修改的。
locals {
inference = [
{ "data_uri" : "s3://my_bucket/model.tar.gz" },
{ "data_uri" : "s3://my_bucket_2/model.tar.gz" },
{ "data_uri" : "s3://my_bucket_3/model.tar.gz" }
]
uri_bucket_map = {
for x in local.inference : x.data_uri =>
split("/", split("//", x.data_uri)[1])[0]
}
}
resource "aws_s3_access_point" "s3_access_point" {
for_each = local.uri_bucket_map
bucket = each.value
name = var.s3_access_point_name
}
output "s3_access_point" {
value = { for uri, ap in aws_s3_access_point.s3_access_point : uri => ap.arn }
}在这个迭代中,我们生成一个从data_uri到bucket_name的映射,以便您可以在需要时访问这两个映射。当然,您仍然可以使用uri的toset版本并在资源中计算桶,但是由于您更喜欢这个方法,所以您可以访问其他地方的桶名,所以我使用了映射。
在创建资源之后,我们生成一个输出,即从data_uri到访问点arn的映射。
发布于 2022-08-15 17:31:14
函数文档包括一个包含用于匹配URL的方案和权限部分的模式的示例,这是对RFC 3986附录B中给出的模式的简化。
regex(“^(?:(?P^:/?#+))”?(?://(?P^/?#*))?“,”https://terraform.io/docs/"“{ "terraform.io”方案“= "https”}
这些S3 URL似乎遵循通常的URL生成,因此解析这些URL的一种方法是通过相同的regex模式运行它们:
> regex("^(?:(?P<scheme>[^:/?#]+):)?(?://(?P<authority>[^/?#]*))?", "s3://my_bucket/model.tar.gz")
{
"authority" = "my_bucket"
"scheme" = "s3"
}为此,我首先从local.inference获得一个新值,该值扩展了这些URL:
locals {
data_uris = [
for o in local.inference : merge(
{uri = o.data_uri},
regex("^(?:(?P<scheme>[^:/?#]+):)?(?://(?P<authority>[^/?#]*))?", o.data_uri),
)
]
}上面的merge是将regex结果与原始输入URI组合起来,为每个输入获得一个简单的对象:
[
{
uri = "s3://my_bucket/model.tar.gz",
scheme = "s3"
authority = "my_bucket"
},
{
uri = "s3://my_bucket_2/model.tar.gz",
scheme = "s3"
authority = "my_bucket_2"
},
{
uri = "s3://my_bucket_3/model.tar.gz",
scheme = "s3"
authority = "my_bucket_3"
},
]然后,我们可以在for_each中进行更多的过滤/投影,将其转换为一组桶名,如果没有设置var.create,则将它们全部过滤掉,并跳过任何不是S3 URL的内容:
resource "aws_s3_access_point" "s3_access_point" {
for_each = toset([
for ap in local.data_uris : ap.authority
if var.enabled && ap.scheme == "s3"
])
bucket = each.key
name = "${each.key}-access-point"
}在这里使用regex显然并不理想,因为很不清楚regex模式正在做什么。如果您继续这样做,那么我建议包括源代码注释,注意这个regex正在解析URI,并可能链接到RFC 3986附录B来解释该模式。
https://stackoverflow.com/questions/73340731
复制相似问题