You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform漂移检测脚本异常:grep过滤失效输出完整Plan内容

Terraform配置漂移检测脚本问题修复

问题说明

编写Shell脚本检测Terraform配置漂移时,将terraform plan的输出过滤后存入tf_plan变量,但脚本执行时会输出完整的Plan内容,而非预期的过滤结果。手动执行单条命令可得到正确输出,但脚本运行不符合预期。

用户脚本

i=environment
terraform init
tf_plan=$(terraform plan | grep -v "Refreshing state" | grep -v "data")
drift_check=`echo $tf_plan | grep -c 'to add\|to change\|to destroy'`
if [[ $drift_check -ge 1 ]]
then
   echo "Drift detected in environment $i"
   printf "%s:%s" "$i" "`echo $tf_plan | grep -E 'to add|to change|to destroy'`"
else
   echo "No drift detected in environment $i"
   printf "%s:%s" "$i" "`echo $tf_plan | grep -E 'No changes'`"
fi

预期输出(存在漂移时)

environment:Plan: 0 to add, 1 to change, 0 to destroy.

手动执行结果

echo $tf_plan | grep -c 'to add\|to change\|to destroy'
1

echo $tf_plan | grep -E 'to add|to change|to destroy'
Plan: 0 to add, 1 to change, 0 to destroy.

printf "%s:%s" "$i":"`echo $tf_plan | grep -E 'to add|to change|to destroy'`"
environment:Plan: 0 to add, 1 to change, 0 to destroy

脚本执行时tf_plan的实际内容

Terraform used the selected providers to generate the following execution
plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # elasticstack_elasticsearch_index.idx1 will be updated in-place
  ~ resource "elasticstack_elasticsearch_index" "idx_salesorder_2019_v6" {
        id                     = "xyzadcfgd/idx1"
      ~ mappings               = jsonencode(
          ~ {
              ~ properties = {
                  ~ address            = {
                      ~ properties = {
                          ~ addressdetails = {
                              ~ properties = {
                                  - streetlocation      = {
                                      - fields = {
                                          - keyword = {
                                              - ignore_above = 256
                                              - type         = "keyword"
                                            }
                                        }
                                      - type   = "text"
                                    }
                                    # (30 unchanged attributes hidden)
                                }
                            }
                            # (1 unchanged attribute hidden)
                        }
                    }
                    # (3 unchanged attributes hidden)
                }
            }
        )
        name                   = "idx1"
        # (8 unchanged attributes hidden)

        # (9 unchanged blocks hidden)
    }
Plan: 0 to add, 1 to change, 0 to destroy.

问题原因

  1. 过滤规则无效:当前grep -v "Refreshing state" | grep -v "data"仅排除包含指定字符串的行,但Terraform Plan的资源详情行不包含这些内容,因此全部保留在tf_plan变量中。
  2. 变量引用未加双引号:echo $tf_plan会将变量中的换行符转换为空格,导致文本格式混乱,虽然手动执行时能侥幸匹配到目标行,但脚本中变量本身包含大量冗余内容,最终输出不符合预期。

修复方案

方案1:精准过滤Terraform Plan输出

直接提取关键行(Plan:或No changes开头的行),减少变量冗余:

i=environment
terraform init
# 仅保留包含Plan:或No changes的行
tf_plan=$(terraform plan | grep -E 'Plan:|No changes')
drift_check=$(echo "$tf_plan" | grep -c 'to add\|to change\|to destroy')
if [[ $drift_check -ge 1 ]]
then
   echo "Drift detected in environment $i"
   printf "%s:%s\n" "$i" "$(echo "$tf_plan" | grep -E 'to add|to change|to destroy')"
else
   echo "No drift detected in environment $i"
   printf "%s:%s\n" "$i" "$(echo "$tf_plan" | grep -E 'No changes')"
fi

方案2:优化变量引用与过滤逻辑

如需保留更多上下文,确保变量引用时加双引号,避免格式丢失:

i=environment
terraform init
tf_plan=$(terraform plan | grep -v "Refreshing state" | grep -v "data")
# 使用here string传递变量,避免echo的格式转换问题
drift_check=$(grep -c 'to add\|to change\|to destroy' <<< "$tf_plan")
if [[ $drift_check -ge 1 ]]
then
   echo "Drift detected in environment $i"
   printf "%s:%s\n" "$i" "$(grep -E 'to add|to change|to destroy' <<< "$tf_plan")"
else
   echo "No drift detected in environment $i"
   printf "%s:%s\n" "$i" "$(grep -E 'No changes' <<< "$tf_plan")"
fi

关键优化点

  • 变量引用时始终加双引号("$tf_plan"),保留原始换行和格式。
  • 使用<<< here string替代echo $tf_plan | grep,减少子进程开销,避免格式转换问题。
  • 精准过滤Terraform输出,只保留需要的关键行,避免变量存储冗余内容。

内容的提问来源于stack exchange,提问作者Bhanu Pratap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 19:45:03