首页 > 解决方案 > 仅在初始创建时设置 Terraform 变量

问题描述

我想知道如果已经创建了给定的资源,是否可以设置 Terraform 变量的值。

我的 Terraform 项目管理许多无状态资源,但也管理一个有状态资源:数据库。基础设施第一次到位时,我们想要初始化(导入)数据库,但不是下一次(当根据 Terraform 声明升级无状态资产时)。此导入由 EC2 实例的用户数据脚本完成(编辑:EC2 实例是无状态的,我们将 DB 导入命令放在其 user_data 中是为了方便并限制从 EC2 实例对 RDS DB 的访问)。

我们在用户数据脚本中检测是否是第一次并不明显(这需要开发)。所以现在我可以看到两个选项:

你知道我的第二点是否可行吗?

标签: terraform

解决方案


一般来说,从 Terraform 自己的角度来看,被管理的远程对象(可能在相关提供者的帮助下)有责任处理诸如仅在初始创建时采取行动的问题,如果这样的事情对特定对象有意义的话。

例如,从 Terraform 的角度来看user_data,它只是要传递给 AWS 提供商的任意字符串,而 AWS 提供商又将其视为要传递给 AWS API 的任意字符串,而 AWS API 又将其视为EC2 实例中的软件可以检索的任意字符串。但是由于在您的 EC2 实例中运行的软件可以保留状态(在磁盘上),因此该软件可能会跟踪“首次启动”与“后续启动”的概念,并据此采取不同的操作。许多 AMI 包括CloudInit作为解释软件user_data,而且该软件确实跟踪第一次引导和后续引导,以便它的某些模块在这两种情况下表现不同。

这种模型是否可以应用于其他资源类型将取决于相应的远程对象具有哪些功能,或者该系统的 Terraform 提供者在远程系统功能之上分层了哪些附加功能。例如,原则上数据库实例的资源类型实现可以包括一些仅在初始创建期间考虑的参数,尽管我不知道您使用的特定资源类型是否具有这种能力。

话虽如此,数据库自然是一个有状态的对象,因此可以直接检查它以确定它是否已被填充,而无需 Terraform 的帮助。我认为对您的潜在问题最可靠的答案是负责填充数据库的系统首先连接到数据库并查看它是否已被填充,如果是,则不执行任何操作。这样,数据库状态的真实来源就是数据库本身,您无需处理该信息的代理(例如,在 Terraform 状态中)可能与现实不同步的尴尬情况。


推荐阅读