When deploying a Windows EC2 instance with Terraform, I want to create a user using the User_Data template. I am also passing a random_password variable to the template. In the main.tf I have:
resource "random_password" "password" {
length = 16
special = true
}
resource "aws_instance" "webserver" {
ami = data.aws_ami.WindowsServer2025.image_id
instance_type = "t3.micro"
key_name = "deployer"
subnet_id = aws_subnet.public_sn1.id
associate_public_ip_address = true
security_groups = [aws_security_group.web_server_sg.id]
user_data = templatefile("New_User.tftpl", { MYPASSWORD = random_password.password.result })
}
For my New_User.tftpl I have:
<powershell>
New-LocalUser -Name User123 -Password (${MYPASSWORD} | ConvertTo-SecureString -AsPlainText -Force)
Add-LocalGroupMember -Group "Administrators" -Member "User123"
</powershell>
... the account is not created. Any idea where it might have gone wrong? thank you.
Solved:
Stupid, just missing quotes:
New-LocalUser -Name User123 -Password ("${MYPASSWORD}" | ConvertTo-SecureString -AsPlainText -Force)
When deploying a Windows EC2 instance with Terraform, I want to create a user using the User_Data template. I am also passing a random_password variable to the template. In the main.tf I have:
resource "random_password" "password" {
length = 16
special = true
}
resource "aws_instance" "webserver" {
ami = data.aws_ami.WindowsServer2025.image_id
instance_type = "t3.micro"
key_name = "deployer"
subnet_id = aws_subnet.public_sn1.id
associate_public_ip_address = true
security_groups = [aws_security_group.web_server_sg.id]
user_data = templatefile("New_User.tftpl", { MYPASSWORD = random_password.password.result })
}
For my New_User.tftpl I have:
<powershell>
New-LocalUser -Name User123 -Password (${MYPASSWORD} | ConvertTo-SecureString -AsPlainText -Force)
Add-LocalGroupMember -Group "Administrators" -Member "User123"
</powershell>
... the account is not created. Any idea where it might have gone wrong? thank you.
Solved:
Stupid, just missing quotes:
New-LocalUser -Name User123 -Password ("${MYPASSWORD}" | ConvertTo-SecureString -AsPlainText -Force)
Share
Improve this question
edited 2 days ago
mklement0
439k68 gold badges701 silver badges912 bronze badges
asked Feb 17 at 22:10
kfkenshinkfkenshin
293 bronze badges
2
- You should not put any sensitive data in user data like passwords. The user data is not encrypted and will be readable inside and outside the ec2 instance. – Chris Doyle Commented Feb 18 at 7:20
- Glad you found a solution, but, in general, it's better to post it in the form of an answer post (which you can later self-accept in order to readily signal to future readers that you've found an effective solution). In the case at hand, I'm hoping my answer will do. – mklement0 Commented 2 days ago
1 Answer
Reset to default 0You've found a solution yourself, but let me add an explanation, point out pitfalls, and offer an alternative:
When you use interpolation in a Terraform string template (such as ${MYPASSWORD}
in your case), the referenced value is (a) stringified, if necessary, and (b) embedded as-is in the string.
Therefore, in order to make your PowerShell command see the value of ${MYPASSWORD}
as a string literal, you must quote it to satisfy PowerShell's syntax requirements:
While using
"..."
, i.e. an expandable (interpolating) string, is an option, note that it makes the Terraform-interpolated value subject to another round of interpolation by PowerShell, so that, say, a verbatim password value such as&#$foo!
would cause PowerShell to expand variable reference$foo
, resulting in undesired modification of the value.Using
'...'
, i.e. a verbatim string, avoids this problem.
With either quoting style, using a regular, inline PowerShell string literal, you must ensure that the Terraform-interpolated value doesn't itself contain the specific quoting characters being used ("
or '
).
If you cannot ensure that, use a here-string literal instead (@'<newline>...<newline>'@
for the verbatim form):
<powershell>
New-LocalUser -Name User123 -Password (
@'
${MYPASSWORD}
'@ | ConvertTo-SecureString -AsPlainText -Force)
Add-LocalGroupMember -Group "Administrators" -Member "User123"
</powershell>
Note that the closing delimiter of a here-string, '@
in the case of a verbatim here-string, must be at the very start of the line in order to be recognized as such.