无法从GitHub Action传递输入变量到Terraform Plan的问题排查
背景
我有一个名为createVnet的GitHub Action,接收来自output_stuff任务的输入,已确认output_stuff传递的输入正确,但执行Terraform Plan时,除Azure认证及状态相关变量外,所有自定义变量均报错未设置值。
工作流配置
createVNET: uses: redacted/redacted/.github/workflows/plan.yml@main with: ref: "main" AZURE_TENANT_ID: "redacted" AZURE_CLIENT_ID: "redacted" AZURE_SUBSCRIPTION_ID: "redacted" state_resource_group: "redacted" state_storageaccount: "redacted" state_container: "redacted" tgtrg: ${{needs.output_stuff.outputs.tgtrg}} tgtvnet: ${{needs.output_stuff.outputs.tgtvnet}} tgtlocation: ${{needs.output_stuff.outputs.tgtlocation}} tgtAddress: ${{needs.output_stuff.outputs.vnet}} tgtSubnet: ${{needs.output_stuff.outputs.subnet}} subnetName: ${{needs.output_stuff.outputs.name}} delegationName: ${{needs.output_stuff.outputs.delegationName}} delegationAction : ${{needs.output_stuff.outputs.delegationAction}} secrets: inherit needs: output_stuff
workflow_call输入定义
workflow_call: inputs: ref: type: string description: "要使用的工作流仓库引用" state_resource_group: type: string description: "包含state_storageaccount定义的Azure存储账户的资源组名称" required: true state_storageaccount: type: string description: "用于存储此工作流Terraform状态的Azure存储账户" required: true state_container: type: string description: "Azure存储账户中用于存储此工作流Terraform状态的容器" required: true tgtrg: type: string description: "UDLR将部署到的资源组名称" required: true tgtlocation: type: string description: "UDLR所在的Azure区域" required: true tgtvnet: type: string description: "虚拟网络名称" required: true tgtAddress: type: string description: "根CIDR" required: true tgtSubnet: type: string description: "目标子网" required: true subnetName: type: string description: "子网名称" required: true delegationName: description: "是否需要委托?" type: string required: false delegationAction: description: "委托操作类型" required: false type: string azure_client_id: type: string description: "Azure客户端ID" required: true azure_tenant_id: type: string description: "包含客户端ID的Azure租户ID" required: true azure_subscription_id: type: string description: "Azure订阅ID" required: true tags: type: string description: "逗号分隔的标签列表,格式为key|value" required: false tf_debug: type: boolean description: "启用Terraform调试日志" default: true required: false secrets: application_id: description: "用于认证拉取私有Action的GitHub应用ID" required: true application_private_key: description: "对应GitHub应用ID的私钥" required: true
环境变量转换步骤
- uses: actions/setup-node@v4 with: node-version: '20' - uses: hashicorp/setup-terraform@v3 - name: 检查目标资源组 if: "${{ inputs.tgtrg != '' }}" shell: bash run: echo "TF_VAR_tgtrg=${{ inputs.tgtrg }}" >> "$GITHUB_ENV" - name: 检查目标资源组区域 if: "${{ inputs.tgtlocation != '' }}" shell: bash run: echo "TF_VAR_tgtlocation=${{ inputs.tgtlocation }}" >> "$GITHUB_ENV" - name: 检查目标虚拟网络名称 if: "${{ inputs.tgtvnet != '' }}" shell: bash run: echo "TF_VAR_tgtvnet=${{ inputs.tgtvnet }}" >> "$GITHUB_ENV" - name: 检查目标子网CIDR if: "${{ inputs.tgtAddress != '' }}" shell: bash run: echo "TF_VAR_tgtAddress=${{ inputs.tgtAddress }}" >> $GITHUB_ENV - name: 检查目标子网名称 if: "${{ inputs.subnetName != '' }}" shell: bash run: echo "TF_VAR_subnetName=${{ inputs.subnetName }}" >> "$GITHUB_ENV" - name: 检查委托名称 if: "${{ inputs.delegationName != '' }}" shell: bash run: echo "TF_VAR_delegationName=${{ inputs.delegationName }}" >> "$GITHUB_ENV" - name: 检查委托操作 if: "${{ inputs.delegationAction != '' }}" shell: bash run: echo "TF_VAR_delegationAction=${{ inputs.delegationAction }}" >> "$GITHUB_ENV"
Terraform Plan步骤配置
- name: Terraform Plan id: plan shell: bash env: ARM_CLIENT_ID: ${{ inputs.AZURE_CLIENT_ID }} ARM_TENANT_ID: ${{ inputs.AZURE_TENANT_ID }} ARM_SUBSCRIPTION_ID: ${{ inputs.AZURE_SUBSCRIPTION_ID }} run: terraform -chdir=${{ inputs.state_container }} plan -no-color -input=false
问题详情
转换环境变量步骤已输出正确的TF_VAR_*变量,但执行Terraform Plan时,所有自定义变量均报错未设置值,例如:
Error: No value for required variable
on main.tf line 69: 69: variable "delegationName" {
The root module input variable "delegationName" is not set...
main.tf中变量定义示例:
variable "tgtvnet" { description = "虚拟网络名称" type = string default = "" }
解决方法
1. 修正输入参数大小写不匹配问题
GitHub Action的inputs是大小写敏感的:
- 工作流调用时传递的
AZURE_TENANT_ID、AZURE_CLIENT_ID、AZURE_SUBSCRIPTION_ID,与workflow_call定义的azure_tenant_id、azure_client_id、azure_subscription_id(全小写)不匹配,会导致输入无法正确映射。 - 修正工作流调用中的参数名,与
workflow_call定义保持一致:
createVNET: uses: redacted/redacted/.github/workflows/plan.yml@main with: # ... 其他参数 ... azure_tenant_id: "redacted" azure_client_id: "redacted" azure_subscription_id: "redacted" # ... 其他参数 ...
2. 移除不必要的空值判断
当前步骤中使用if: "${{ inputs.tgtrg != '' }}"的判断逻辑,若输入为空字符串(但required: true的变量不会为空),会跳过环境变量设置。Terraform变量即使有默认值,也需要确保TF_VAR变量存在(哪怕值为空)。可以合并步骤并去掉if条件:
- name: 设置Terraform环境变量 shell: bash run: | echo "TF_VAR_tgtrg=${{ inputs.tgtrg }}" >> "$GITHUB_ENV" echo "TF_VAR_tgtlocation=${{ inputs.tgtlocation }}" >> "$GITHUB_ENV" echo "TF_VAR_tgtvnet=${{ inputs.tgtvnet }}" >> "$GITHUB_ENV" echo "TF_VAR_tgtAddress=${{ inputs.tgtAddress }}" >> "$GITHUB_ENV" echo "TF_VAR_subnetName=${{ inputs.subnetName }}" >> "$GITHUB_ENV" echo "TF_VAR_delegationName=${{ inputs.delegationName }}" >> "$GITHUB_ENV" echo "TF_VAR_delegationAction=${{ inputs.delegationAction }}" >> "$GITHUB_ENV"
3. 验证环境变量是否正确传递
在Terraform Plan步骤前添加打印命令,确认TF_VAR_*变量存在:
- name: 打印Terraform环境变量 shell: bash run: env | grep TF_VAR_
4. 检查Terraform变量名与TF_VAR前缀的一致性
确保TF_VAR_后的变量名与main.tf中定义的变量名完全一致(大小写匹配),例如main.tf中是delegationName,则TF_VAR_delegationName是正确的。
内容的提问来源于stack exchange,提问作者pcam

