【问题标题】:Terraform timestamp() to numbers only string将时间戳()转换为仅数字字符串
【发布时间】:2019-07-01 01:10:19
【问题描述】:

插值语法中的timestamp() 函数将返回一个ISO 8601 格式的字符串,类似于2019-02-06T23:22:28Z。但是,我想要一个看起来像这样20190206232240706500000001 的字符串。一个只有数字(整数)且没有连字符、空格、冒号、Z 或 T 的字符串。有什么简单而优雅的方法来实现这一点?

如果我在连字符、空格、冒号 Z 和 T 时替换每个单个字符类,它会起作用:

locals {
  timestamp = "${timestamp()}"
  timestamp_no_hyphens = "${replace("${local.timestamp}", "-", "")}"
  timestamp_no_spaces = "${replace("${local.timestamp_no_hyphens}", " ", "")}"
  timestamp_no_t = "${replace("${local.timestamp_no_spaces}", "T", "")}"
  timestamp_no_z = "${replace("${local.timestamp_no_t}", "Z", "")}"
  timestamp_no_colons = "${replace("${local.timestamp_no_z}", ":", "")}"
  timestamp_sanitized = "${local.timestamp_no_colons}"
}

output "timestamp" {
  value = "${local.timestamp_sanitized}"
}

结果输出是所需格式,除了字符串明显更短:

Outputs:

timestamp = 20190207000744

但是,这个解决方案非常难看。是否有另一种方法可以以更优雅的方式执行相同的操作,并生成与示例字符串 20190206232240706500000001 长度相同的字符串?

【问题讨论】:

    标签: terraform hcl


    【解决方案1】:

    Terraform 0.12.0 引入了一个新函数formatdate,它可以使它更具可读性:

    output "timestamp" {
      value = formatdate("YYYYMMDDhhmmss", timestamp())
    }
    

    在撰写本文时,formatdate 支持的最小单位是整秒,因此这不会给出与正则表达式方法完全相同的结果,但如果最近的秒足够准确以供使用,则可以工作 -案例。

    【讨论】:

    • 现在应该将其标记为答案,因为 0.12 支持此功能
    • 我试过了,它每次都生成相同的时间戳而不是实时,你知道为什么吗?
    【解决方案2】:

    当前的interpolate function timestamp()已经在源代码中硬编码为RFC3339的输出格式:

    https://github.com/hashicorp/terraform/blob/master/config/interpolate_funcs.go#L1521

    返回时间.Now().UTC().Format(time.RFC3339),无

    所以你的方式没有问题,但是我们可以稍微改进一下。

    locals {
      timestamp = "${timestamp()}"
      timestamp_sanitized = "${replace("${local.timestamp}", "/[- TZ:]/", "")}"
    
    }
    

    参考:

    https://github.com/google/re2/wiki/Syntax

    replace(string, search, replace) - 对给定的字符串进行搜索和替换。所有的 search 实例都被替换为 replace 的值。如果搜索包含在正斜杠中,则将其视为正则表达式。如果使用正则表达式,replace 可以使用 $n 引用正则表达式中的子捕获,其中 n 是子捕获的索引或名称。如果使用正则表达式,语法符合 re2 正则表达式语法

    【讨论】:

    • 你能解释一下管道是什么吗?符号呢?这只是 re2 语法中的 OR 吗?
    • 主要是。建议学习一些Regex(正则表达式)教程,这样你就可以轻松理解这些字符的用法了
    • 谢谢。正则表达式语法有不同的变体。 Re2 可能是确定性有限自动机 (DFA) 和常规语言的最具学术性的版本。 | 符号仅表示 re2 语法中的 or。但是,不太清楚的是 Terraform replace 方法会替换任何出现的正则表达式字符串。
    • / 用于表示正则表达式的开头,[] 将搜索词组合在一起。 [-| |T|Z|:] 的书面解释是搜索任何出现的单个破折号- 或单个空格` ` 或单个T 或单个Z 或单个冒号: 并将其替换为空""
    • @Jeepler 或任何可能来到这里的人,[-| |T|Z|:] 是不正确的,因为方括号内的管道符号不能用作 OR 并且将匹配字符 |。方括号内的字符集已经是可以选择的,所以你只需要[- TZ:],这意味着你不需要|
    【解决方案3】:

    此答案仅显示了@BMW 答案的示例,这对于 Terraform 的新手来说并不明显。

    $ cat main.tf
    locals {
      timestamp = "${timestamp()}"
      timestamp_sanitized = "${replace("${local.timestamp}", "/[-| |T|Z|:]/", "")}"
    
    }
    
    output "timestamp" {
      value = "${local.timestamp_sanitized}"
    }
    

    示例运行

    运行#1:

    $ terraform apply
    
    Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
    
    Outputs:
    
    timestamp = 20190221205825
    

    运行#2:

    $ terraform apply
    
    Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
    
    Outputs:
    
    timestamp = 20190221205839
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-22
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      • 1970-01-01
      • 2016-11-30
      • 2017-07-29
      • 2013-09-25
      相关资源
      最近更新 更多