Search code examples
terraformaws-glueterraform-template-file

Invalid Template Control Keyword


Currently developing a TF template inclusive of some glue services. When attempting to init the template, I am prompted with the below error:

Error: Invalid template control keyword

on main.tf, in resource "aws_glue_classifier" "SrcPlanClassifier":
grok_pattern   = "%{DATA:col},%{DATA:col2},%{DATA:col3},"%{DATA:col4}",% . 
{DATA:col5},%{DATA:col6},%{DATA:col7},%{DATA:col8},%{DATA:col9},%{DATA:col10},% . 
{DATA:col11},%{DATA:col12},%{DATA:col}13$"

"DATA" is not a valid template control keyword.

This template is the result of translating an existing CloudFormation template to Terraform, so the pattern has worked in the past. From what I can tell in the AWS documentation for Glue, the DATA term is an acceptable built-in classifier. That implies to me that this is an issue on the Terraform end. What am I missing here?

Thanks in advance for the help!


Solution

  • Terraform is understanding the %{ sequences as introducing a template directive, which then fails because if and for are the only keywords that are allowed to follow that %{ marker in the Terraform language.

    To use %{ literally in your string, you can write %%{ instead to escape the introducer. Terraform will see %%{ and produce %{ in the resulting string:

    grok_pattern   = "%%{DATA:col},%%{DATA:col2},%%{DATA:col3},"%%{DATA:col4}",% . 
    {DATA:col5},%%{DATA:col6},%%{DATA:col7},%%{DATA:col8},%%{DATA:col9},%%{DATA:col10},% . 
    {DATA:col11},%%{DATA:col12},%%{DATA:col}13$"
    

    (I think there were some line-wrapping problems in the message you shared so I've updated it as best I could for the escaping but you may need to do some additional escaping yourself. The general idea is to replace every %{ with %%{ in your quoted string.)


    Another option, for complicated expressions whose readability is hurt significantly by this much escaping, is to move the relevant string into a separate file and then have Terraform read that file:

      grok_pattern = file("${path.module}/grok_pattern.txt")
    

    The file function just takes the text in the given file verbatim, and does not parse it for template sequences or any other special markers.