Reputation: 193
I have a big file of variables in .tf file and I want to change values using bash script .
like my file have many chunks like this and I want to change each one step by step .what will be best practice to change terraform file variables values ?
variable "azure_spoke_gateways" {
default = {
spoke1 = {
name = "name"
size = "size"
vpc = ""
},
spoke2 = {
name = "dummy"
size = "size2"
}
}
}
Upvotes: 1
Views: 2588
Reputation: 1653
If you own the file and can produce it from scratch, rather than editing an existing one, you could use the following approach.
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
Though it's limited to a certain kind of scenarios, but very simple and straightforward.
Upvotes: 3
Reputation: 12877
Using GNU awk:
Set the variables before proceeding
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
Pass these variable into GNU awk with -v
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
One liner
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
If you have a recent version of GNU awk, you can commit the changes to the file by simply adding the -i flag and so:
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
Otherwise:
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
Upvotes: 2
Reputation: 272267
If you store your variables in a Terraform JSON format, I'd recommend using something JSON-aware, such as JQ, rather than naively modifying the JSON using sed
/awk
etc. That way you should be able to reliably maintain your JSON format.
If you need to maintain the original format, which I understand is HCL, maybe write a script using an HCL parser, such as this one
Upvotes: 1