使用Terraform资源上的当前GIT信息



我想用GIT修订哈希、ref名称标记Terraform创建的资源,并记录签出是干净的还是脏的。我找到了一个git提供程序,它提供了一些信息,但不是全部信息。我想通知查看实际资源的运营商,最后由谁部署了什么。

Terraform没有与版本控制系统的内置集成,但有三种主要方法可以将类似的外部信息获取到Terraform中:

  1. 您可以在执行时使用根模块中声明的输入变量将数据传递到配置中。

    为了使用这种方法;系统的";数据收集必须始终一致进行,您通常需要将Terraform包装在包装脚本或远程自动化中,以确保每次都一致地收集和传递数据。

  2. 您可以使用提供商提供的数据源,在这种情况下,Terraform将在规划步骤中从中读取数据,并将数据公开给模块的其他地方使用。

    你链接到的Git提供程序就是这个策略的一个例子。在使用中提到的git_repository(至少在我写这篇文章的时候(就是数据源的一个例子。

    如果该提供商没有提供您需要的所有数据,那么您可以为其提供额外的功能,因为它是开源的,或者您可以编写自己的提供商,更直接地满足您的需求。

  3. 作为前面选项的变体,hashicorp/external提供程序包括一个称为external的特殊通用数据源,该数据源通过运行特定的外部程序来获得数据,只要该程序以提供程序理解的规定格式生成输出即可。

    如果还没有提供更专业数据源的提供商,这可能是一个方便的逃生通道,但它确实引入了对Terraform直接范围之外的外部软件的依赖,这可能会使在可能安装了不同软件或软件版本的不同操作系统中使用Terraform配置变得更加复杂。

这些都是适用于任何源自Terraform配置之外的数据的通用机制。由于Terraform本身并不知道您的版本控制系统,因此有关该系统状态的信息被视为来自外部。


请注意,在基础设施对象的属性中直接公开这种元数据有一些缺点。

最值得注意的是,如果你这样做的范围很广,那么这意味着你对配置所做的任何更改都可能导致Terraform建议就地更新配置中声明的大部分或全部资源实例。这意味着一个特别嘈杂的差异,可能会使Terraform提供商更难看到他们提议做出的更重大的改变。

如果您选择这样做,我建议您只在配置中的单个位置公开它,而不是在所有基础结构对象中填充标记。例如,您可以将信息写入输出值,然后您可以使用terraform output来查看Terraform State中记录的根模块输出值的最新值,然后;嘈杂的";每个新提交的更改将只是修改少量输出值,而不是对任何实际基础设施进行更改。

如果jqgit命令可用,则可以使用external数据源获取所需信息。它需要json的输出——stringstring的映射。然后以结构化的方式将其作为result属性提供。您还可以添加其他上下文信息,例如gitlab管道信息。

考虑到这几乎每次都会触发更改,所以要谨慎使用频繁更改的信息。我只标记主资源组。

考虑一下警告-外部数据源是一个逃生舱口。您最好确定,在运行Terraform配置的任何地方,这些工具的行为都是相同的。

data "external" "git" {
program = ["sh", "-c", <<-EOSCRIPT
jq -n '{ "rev": $REV, "ref": $REF, "status": $STT, "clean": $CLN, "user": $USR, "repo": $REP, "job": $JOB, "pipeline": $PIP }' 
--arg REV "$(git rev-parse --verify HEAD)" 
--arg REF "$(git symbolic-ref HEAD || echo '(DETACHED)')" 
--arg STT "$(git diff --quiet && echo "# CLEAN" || git status --porcelain)" 
--arg CLN "$(git diff --quiet && echo yes || echo no)" 
--arg USR ""$${GITLAB_USER_LOGIN:-$(git config user.name)}" <$${GITLAB_USER_EMAIL:-$(git config user.email)}>" 
--arg REP "$(git remote get-url origin)" 
--arg JOB "$CI_JOB_URL" 
--arg PIP "$CI_PIPELINE_URL"
EOSCRIPT
]
}
// short cut for easier use
// usage: local.git.rev
locals {
git = data.external.git.result
}
// for information
output "git" {
value = local.git
}

这段代码负责转义,这样您就不会遇到无效的JSON或格式错误的命令行问题。Terraform在命令出现问题时会产生整洁的错误反馈:

最新更新