使用 bash 脚本编辑 .tf 变量文件

Posted

技术标签:

【中文标题】使用 bash 脚本编辑 .tf 变量文件【英文标题】:edit .tf variable files using bash script 【发布时间】:2021-03-23 18:59:20 【问题描述】:

我在 .tf 文件中有一个很大的变量文件,我想使用 bash 脚本更改值。

就像我的文件有很多这样的块,我想逐步更改每个块。更改 terraform 文件变量值的最佳做法是什么?

variable "azure_spoke_gateways" 
  default = 
    spoke1 = 
      name         = "name"
      size         = "size"
      vpc          = ""
    ,
    spoke2 = 
      name         = "dummy"
      size         = "size2"
    
  

【问题讨论】:

【参考方案1】:

如果您拥有该文件并且可以从头开始生成它,而不是编辑现有文件,您可以使用以下方法。

cat << EOF > main.tf.sh
variable "azure_spoke_gateways" 
  default = 
    spoke1 = 
      name    = "AZ-$region-Spoke1-GW"
      size       = "Standard_B1ms"
      .. 
    
  

EOF
chmod +x main.tf.sh

export region=EU
. ./main.tf.sh > main.tf

虽然仅限于某种场景,但非常简单明了。

【讨论】:

感谢您的回答,但我只能使用bash script编辑它【参考方案2】:

使用 GNU awk:

在继续之前设置变量

spke="spoke1" # The spoke we are concerned with
var="size" # The variable within the spoke section we are concerned with
val="size1" # The value we want to change to.
clp="azure" # Either azure or aws

使用 -v 将这些变量传递到 GNU awk

awk -v spke="$spke" -v var="$var" -v val="$val" -v clp="$clp"'
      /variable/  
                                      cloudp=gensub(/(^variable[[:space:]]")(.*)(".*$)/,"\\2",$0) # Pull out the cloud provider
                 
      /spoke[[:digit:]][[:space:]]=/  
                                        spoke=$1 # Track the spoke section
                                      
          spoke==spke && $1==var && cloudp ~ clp  # If spoke is equal to the passed spoke and the first space separated field is equal to the variable and clp is equal to the passed cloud provider (clp) we want to change (var)
                                        $0=gensub(/(^.*=[[:space:]]")(.*)(".*$)/,"\\1"val"\\3",$0) # Substitute the value for the value passed (val)
                                     1' file

一个班轮

awk -v spke="$spke" -v var="$var" -v val="$val" -v clp="$clp" '/variable/  cloudp=gensub(/(^variable[[:space:]]")(.*)(".*$)/,"\\2",$0)  /spoke[[:digit:]][[:space:]]=/  spoke=$1  spoke==spke && $1==var && cloudp ~ clp  $0=gensub(/(^.*=[[:space:]]")(.*)(".*$)/,"\\1"val"\\3",$0) 1' file

如果您有最新版本的 GNU awk,您可以通过简单地添加 -i 标志来提交对文件的更改:

awk -i -v spke="$spke" -v var="$var" -v val="$val" -v clp="$clp" '/variable/  cloudp=gensub(/(^variable[[:space:]]")(.*)(".*$)/,"\\2",$0)  /spoke[[:digit:]][[:space:]]=/  spoke=$1  spoke==spke && $1==var && cloudp ~ clp  $0=gensub(/(^.*=[[:space:]]")(.*)(".*$)/,"\\1"val"\\3",$0) 1' file

否则:

awk -v spke="$spke" -v var="$var" -v val="$val" -v clp="$clp" '/variable/  cloudp=gensub(/(^variable[[:space:]]")(.*)(".*$)/,"\\2",$0)  /spoke[[:digit:]][[:space:]]=/  spoke=$1  spoke==spke && $1==var && cloudp ~ clp  $0=gensub(/(^.*=[[:space:]]")(.*)(".*$)/,"\\1"val"\\3",$0) 1' file > file.tmp && mv -f file.tmp file 

【讨论】:

awk 出现问题,如果我运行 awk 命令 2 次,则仅应用最后一项更改。就像我先运行 name change 然后运行 ​​size 。只有改名有效 我使用一个班轮 您必须确保使用 awk -i 或临时文件移动提交更改,如倒数第二个示例的最后一个示例。 我正在使用 otherwise 选项,因为 -i 对我来说不是有效的命令 先生几乎完成了,只是有一个小问题。如果有两个具有相同名称的变量,则 awk 会同时更改。我已经更新了我的问题。请看一下。【参考方案3】:

如果您将变量存储在 Terraform JSON format 中,我建议您使用可识别 JSON 的内容,例如 JQ,而不是使用 sed/awk 等天真地修改 JSON。这样您应该能够可靠地维护您的 JSON 格式。

如果你需要保持原来的格式,我理解是HCL,可以用HCL解析器写一个脚本,比如this one

【讨论】:

遗憾的是它不是 json 并且我已经进行了 6 天的研究 :( 它的格式是 .ts 。如果我想更改 .tf 变量文件值有什么想法吗? 如果原始格式是 HCL,我想你会找到各种不同脚本语言的解析器。如果做不到这一点,您也许可以在简单的情况下使用 sed/awk。 请您举一个pyhcl的小例子吗? 我没用过,我承认

以上是关于使用 bash 脚本编辑 .tf 变量文件的主要内容,如果未能解决你的问题,请参考以下文章

一个bash脚本,用于使用bash脚本连接字符串并在同一文件中编辑一行

从本地 bash 脚本文件夹中编辑 plist

Shell基本脚本命令使用教程

使用 bash 脚本和测试处理进行代码编辑

Shell脚本基本编辑规范及变量

用于编辑 xml 文件的 bash 脚本