user9521823
user9521823

Reputation:

Bash EOF block in EOF block possible?

I'm trying to write in a file a block containing its own EOF block. Is it something doable in bash?

cat > terragrunt.hcl <<'EOF' 
# Automatically generated from script $(basename $0)

# Generate the AWS provider block
generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
# Terragrunt root config
provider "aws" {
  # Only these AWS Account IDs may be operated on by this template
  allowed_account_ids = ["${local.account_id}"]
  region = "${local.infra_region}"
  version = "${local.customer_vars.locals.aws_provider_version}"
}
EOF
}

# Automatically generated from script $(basename $0)
EOF

As expected it is failing with:

❯ ./example.sh 
./example.sh: line 17: syntax error near unexpected token `}'
./example.sh: line 17: `}'

What is the best solution to deal with it?

Upvotes: 2

Views: 943

Answers (1)

IMSoP
IMSoP

Reputation: 97753

What you are calling an "EOF block" is actually called a "Here Document" (commonly abbreviated "heredoc"), and the string "EOF" can actually be any "word" you like.

The heredoc contains everything up to its matching delimiter, so nesting two heredocs is just a case of picking two different delimiters:

cat > terragrunt.hcl <<'ENDTERRAGRUNT' 
# Automatically generated from script $(basename $0)

# Generate the AWS provider block
generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<ENDROOTCONFIG
# Terragrunt root config
provider "aws" {
  # Only these AWS Account IDs may be operated on by this template
  allowed_account_ids = ["${local.account_id}"]
  region = "${local.infra_region}"
  version = "${local.customer_vars.locals.aws_provider_version}"
}
ENDROOTCONFIG
}

# Automatically generated from script $(basename $0)
ENDTERRAGRUNT

Upvotes: 4

Related Questions