terraform - 仅在初始创建时设置 Terraform 变量
问题描述
我想知道如果已经创建了给定的资源,是否可以设置 Terraform 变量的值。
我的 Terraform 项目管理许多无状态资源,但也管理一个有状态资源:数据库。基础设施第一次到位时,我们想要初始化(导入)数据库,但不是下一次(当根据 Terraform 声明升级无状态资产时)。此导入由 EC2 实例的用户数据脚本完成(编辑:EC2 实例是无状态的,我们将 DB 导入命令放在其 user_data 中是为了方便并限制从 EC2 实例对 RDS DB 的访问)。
我们在用户数据脚本中检测是否是第一次并不明显(这需要开发)。所以现在我可以看到两个选项:
- 在调用 的脚本中
terraform apply
,我可以查询 Terraform 状态 (terraform state list
) 以确定数据库是否已存在,并将其terraform apply
作为变量传递给。 - 但是如果可以直接在 Terraform 声明中确定 DB 资源的当前状态(它是否存在)会更简单,所以我可以将它传递给我的用户数据脚本(因此它是否初始化 DB) . 我没有看到如何做到这一点。我看不到任何函数,看起来当我引用资源的属性(例如:RDS DB 的 ID)时,它将在创建资源后计算。
你知道我的第二点是否可行吗?
解决方案
一般来说,从 Terraform 自己的角度来看,被管理的远程对象(可能在相关提供者的帮助下)有责任处理诸如仅在初始创建时采取行动的问题,如果这样的事情对特定对象有意义的话。
例如,从 Terraform 的角度来看user_data
,它只是要传递给 AWS 提供商的任意字符串,而 AWS 提供商又将其视为要传递给 AWS API 的任意字符串,而 AWS API 又将其视为EC2 实例中的软件可以检索的任意字符串。但是由于在您的 EC2 实例中运行的软件可以保留状态(在磁盘上),因此该软件可能会跟踪“首次启动”与“后续启动”的概念,并据此采取不同的操作。许多 AMI 包括CloudInit作为解释软件user_data
,而且该软件确实跟踪第一次引导和后续引导,以便它的某些模块在这两种情况下表现不同。
这种模型是否可以应用于其他资源类型将取决于相应的远程对象具有哪些功能,或者该系统的 Terraform 提供者在远程系统功能之上分层了哪些附加功能。例如,原则上数据库实例的资源类型实现可以包括一些仅在初始创建期间考虑的参数,尽管我不知道您使用的特定资源类型是否具有这种能力。
话虽如此,数据库自然是一个有状态的对象,因此可以直接检查它以确定它是否已被填充,而无需 Terraform 的帮助。我认为对您的潜在问题最可靠的答案是负责填充数据库的系统首先连接到数据库并查看它是否已被填充,如果是,则不执行任何操作。这样,数据库状态的真实来源就是数据库本身,您无需处理该信息的代理(例如,在 Terraform 状态中)可能与现实不同步的尴尬情况。
推荐阅读
- makefile - Makefile 处理多行输出
- linux - Docker 安装问题 (ubuntu 20.04 LTS) - E: 存储库 'https://download.docker.com/linux/ubuntu\Release' 没有 Release 文件
- java - kotlin list group by with sort
- amazon-web-services - raint:成员必须满足正则表达式模式:^(\*\.)?(((?!-)[A-Za-z0-9-]
- ruby-on-rails - Rails + Passenger + Nginx:第二个应用程序的“404 Not Found”
- django - pytest 测试总是返回 abc.is_online True
- ios - 如何调整导航栏的大小?(iOS)
- reactjs - react 在初始化期间返回未定义的键“mods”的切片缩减器。(还原)
- python - tkinter gui 在点击时设置文本
- caching - 自定义域重定向到 firebase 中的 index.html