I am trying to use a Terraform template file to create a sudoers file on a Linux server. I am passing in the name of a group that should be granted sudo permission as a variable to the template.
As per the syntax of the sudoers file, groups need to be prefixed with a % character. Assuming that the group name I want to use is my-admins the expected content of the file/output of the template will be:
%my-admins ALL=(ALL) NOPASSWD:ALL
I therefore need a literal % character followed immediately by a variable, ${group_name}. My first attempt was as follows, but this seems to give me a corrupt sudoers file:
#!/bin/bash
cat > /etc/sudoers.d/90-${group_name} <<-EOT
    %${group_name} ALL=(ALL) NOPASSWD:ALL
EOT
EDIT: Adding some more implementation details
The template is included as follows:
data "template_file" "sudoers" {
    count           = 1
    template        = file("${path.module}/sudoers.tpl")
    vars = {
        group_name  = var.admins_group
    }
}
resource "openstack_compute_instance_v2" "my_server" {
    count           = 1
    name            = "my_server"
    flavor_name     = var.instance_flavor
    security_groups = var.security_group_ids
    user_data = element(data.template_file.sudoers.*.rendered, 0)
    
    # etc.
}
I have tried a number of different escape sequences, focusing mainly on the % character, for example, with the desirable output hard-coded on the first line:
cat > /etc/sudoers.d/90-${group_name} <<-EOT
    %my-group ALL=(ALL) NOPASSWD:ALL
    %${group_name} ALL=(ALL) NOPASSWD:ALL
    \%${group_name} ALL=(ALL) NOPASSWD:ALL
    %%${group_name} ALL=(ALL) NOPASSWD:ALL
    ${group_name} ALL=(ALL) NOPASSWD:ALL
EOT
This gives the following output; only the first line is valid:
    %my-group ALL=(ALL) NOPASSWD:ALL
    % ALL=(ALL) NOPASSWD:ALL
    \% ALL=(ALL) NOPASSWD:ALL
    %%my-group ALL=(ALL) NOPASSWD:ALL
    my-group ALL=(ALL) NOPASSWD:ALL
As can be seen, the variable appears to be swallowed up on lines 2 and 3, but correctly expanded on lines 4 and 5.
Is there a combination that would allow me to use a variable for the group name with a literal % prefixing it in the output?
And a side note: It seems that my output is being indented; I thought that the hyphen in <<-EOT removed indents?
 
                        
I'm not 100% sure what's going on here, but if all else fails you can force Terraform to see tokens as separate by splitting them into separate interpolation sequences. For example:
The
${"%"}tells Terraform to interpolate a literal%, since there's never any special meaning to%followed by", so Terraform will always understand that%as literal.