Terraform向PowerShell模板传变量及脚本执行相关技术问题
背景信息
我正在用Terraform创建Windows EC2实例,通过user_data指定PowerShell脚本在实例启动后运行。相关Terraform配置如下:
resource "aws_instance" "windows_runner" { ami = var.ami_id instance_type = var.instance_type iam_instance_profile = aws_iam_instance_profile.runner_instance.name key_name = var.key_name security_groups = [aws_security_group.windows.id] subnet_id = data.aws_subnet.work.id tags = var.tags user_data = templatefile("userdata.tftpl", { environment_name = var.environment_name, instance_type = var.instance_type }) }
通过templatefile函数向模板文件传递了environment_name和instance_type两个变量,模板文件内容如下:
<powershell> Set-Location -Path "C:\GitLab-Runner" $token = "sometoken" $url = "https://gitlab-instance.domain.com/" $runner_name = "windows-runner-$instance_type" $executor = "shell" $shell = "powershell" $builds_location = "c:\builds" $tags = "$environment_name-windows-$instance_type" New-Item -Path $builds_location -ItemType Directory -ErrorAction SilentlyContinue Write-Host "$builds_location has been created!" # register runner. Trailing backtick to span on multiple line. White space matters .\gitlab-runner.exe register ` --non-interactive ` --url $url ` --registration-token $token ` --name $runner_name ` --executor $executor ` --shell $shell ` --builds-dir $builds_location ` --tag-list $tags ` --locked="false" .\gitlab-runner.exe install .\gitlab-runner.exe start </powershell>
技术问题
- 这些变量在PowerShell中如何生效?
- 是否可以直接在PS脚本中使用
$environment_name和$instance_type? - 这些变量是否会作为参数传入PS脚本?若如此,是否需要定义并匹配参数名或顺序?
- PS脚本在实例启动后是否会以管理员模式执行?
额外说明:找到较多templatefile在Linux和Shell脚本中的使用示例,但缺乏Windows和PowerShell相关的优质示例。
解答
1. 变量生效机制
Terraform的templatefile函数会在部署阶段完成变量替换:读取模板文件内容后,将传入的environment_name和instance_type变量值,直接替换模板里对应的占位符,生成填充好实际值的完整PowerShell脚本文本,再将这个文本作为user_data传递给EC2实例。实例启动后,EC2用户数据服务执行的是已经完成替换的脚本,PowerShell直接使用脚本里的硬编码值。
2. 能否直接使用$environment_name和$instance_type?
不能直接这么用。模板里的$会被Terraform识别为PowerShell的语法符号,而非Terraform变量的标识。需要改用Terraform模板语法引用变量,将$environment_name改为${environment_name},$instance_type改为${instance_type},示例如下:
$runner_name = "windows-runner-${instance_type}" $tags = "${environment_name}-windows-${instance_type}"
修改后Terraform会正确识别并替换变量,生成的脚本里会是实际的变量值,PowerShell执行时即可正常使用。
3. 变量是否作为参数传入?
不会作为参数传入。Terraform是在部署阶段就完成了变量的文本替换,生成的是填充好值的完整脚本,而非带参数的模板。因此不需要在PowerShell里定义参数或匹配顺序,脚本执行时直接使用替换后的硬编码值即可。
4. 是否以管理员模式执行?
是的。EC2实例启动时,用户数据脚本(包括PowerShell脚本)通过Local System账户执行,该账户拥有系统管理员权限,因此脚本会以管理员模式运行,无需额外提权。
内容的提问来源于stack exchange,提问作者LP13

