英文:
Unable to set environment variable for current session in terraform
问题
我有一个通过terraform local-exec执行的操作,通过它我执行
```bash
export ABC=value
随后的模块内部有一个local-exec,从环境中读取值
echo $ABC > file.txt
当我执行时,会创建一个空的file.txt
文件。位于模块中的第二个local-exec无法从terraform的apply会话中获取值
resource "null_resource" "export_environment_variable" {
triggers = {
always = timestamp()
}
provisioner "local-exec" {
command = "export ABC=value"
}
}
module "module_internal" {
src = "./internal-module"
depends_on = [null_resource.export_environment_variable]
}
/internal-module
resource "null_resource" "write-to-file" {
triggers = {
always = timestamp()
}
provisioner "local-exec" {
command = "echo $ABC > file.txt"
}
}
<details>
<summary>英文:</summary>
I have a terraform local-exec through which I execute
```bash
export ABC=value
The subsequent module has a local-exec internally and reading the value from environment
echo $ABC > file.txt
When i execute is an empty file.txt
is created
The second local-exec which resides in the module is not able to fetch from the apply session in terraform
resource "null_resource" "export_environment_variable" {
triggers = {
always = timestamp()
}
provisioner "local-exec" {
command = "export ABC=value"
}
}
module "module_internal {
src = "./internal-module"
depends_on = [null_resource.export_environment_variable]
}
/internal-module
resource "null_resource" "write-to-file" {
triggers = {
always = timestamp()
}
provisioner "local-exec" {
command = "echo $ABC > file.txt"
}
}
答案1
得分: 1
当你使用 local-exec
如你所示的方式时,Terraform会启动你的shell作为子进程,并要求shell来评估脚本。在脚本评估完成后,shell进程结束,因此任何内存中的状态,如shell变量,都会丢失。
在你的示例中,你有两个独立的 local-exec
provisioners,因此有两个完全独立的shell会话。你在这里所做的类似于如果你按照以下步骤进行操作:
- 在计算机上的一个窗口中打开终端。
- 在该终端中运行
export ABC=value
。 - 在计算机上的另一个独立窗口中打开另一个终端。
- 在该终端中运行
echo $ABC
。
就像Terraform中的两个独立的 local-exec
provisioners一样,这两个终端都有各自独立的shell实例运行,因此不共享内存状态,如shell变量。
如果你想设置一个shell变量,然后以后再使用它,你需要在同一个shell进程中执行这两个操作,这意味着在同一个 local-exec
provisioner 中执行这两个操作:
resource "null_resource" "export_environment_variable" {
triggers = {
always = timestamp()
}
provisioner "local-exec" {
command = <<-EOT
export ABC=value
echo $ABC > file.txt
EOT
}
}
请注意,provisioners是最后的手段,可能有更好的方法来实现这个目标,而不需要使用local-exec
。我在这里关注local-exec
,因为这是你提出问题的内容,但这也许是一个XY问题的示例,如果你有兴趣探索替代解决方案,我建议提出一个新问题,描述你实际的问题,而不要假设provisioners涉及到解决方案。
英文:
When you use local-exec
in the way you've shown, Terraform starts your shell as a child process and asks the shell to evaluate the script. After the script is evaluated, the shell process ends and so any in-memory state such as shell variables are lost.
In your example you have two separate local-exec
provisioners and therefore two separate end entirely independent shell sessions. What you have done here is similar to what might happen if you followed the following steps:
- Open a terminal in a window on your computer.
- In that terminal, run
export ABC=value
. - Open another separate terminal in a separate window on your computer.
- In that terminal, run
echo $ABC
.
Just as with the two separate local-exec
provisioners in Terraform, these two terminals each have their own separate instance of your shell running and so do not share in-memory state such as shell variables.
If you want to set a shell variable and then use it later you will need to do both in the same shell process, which means doing both in the same local-exec
provisioner:
resource "null_resource" "export_environment_variable" {
triggers = {
always = timestamp()
}
provisioner "local-exec" {
command = <<-EOT
export ABC=value
echo $ABC > file.txt
EOT
}
}
Note that provisioners are a last resort and there is probably a better way to achieve this goal that doesn't involve using local-exec
at all. I've focused on local-exec
here because that's what you asked the question about, but this is perhaps an example of XY Problem and if you're interested in exploring alternative solutions I would suggest starting a new question that describes the real problem you have without assuming that provisioners are involved in the solution.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论