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.