How to pass Variables with Secrets (User, Password) in Terraform

Following the documentation I have created Main.tf, Terraform.tfvars, variables.tf,

Main.tf, containing my network cards, HDD, and VM
Terraform.tfvars, containing my two variable values:

TF_VAR_username = "adminuser"
TF_VAR_username = "MySuperPass"

variables.tf, containing the variable declaration:

variable "admin_user" {
  type = string
  }
variable "admin_password" {
  type = string
  }

When I run my terraform code it complains that:
Password is not compliant with the requirements of, lowercase, uppercase, number, symbol

That’s not true, why? well, the same password worked perfectly when declared directly into my Main.tf file, but that is not a good practice because is fully visible and that´s why I want to pass it via a variable to keep it away to be sniff

What am i missing?

Hi @dranenko,

Terraform itself doesn’t have any special functionality for validating passwords, so I must assume that error message is coming from a provider you’re using. If you can share a bit more information about where you’re using that variable then that might allow a better answer!

Focusing only on what you included in the question though, one thing I notice is that both of your examples of environment variable are TF_VAR_username, which doesn’t match the name of either of your variables. To set the two variables you showed, you’d need to set TF_VAR_admin_user and TF_VAR_admin_password respectively.

The environment variable names alone don’t fully explain the error you saw though, because with those declarations Terraform should typically return an error if you don’t set both variables; neither of them have default and so both of them ought to be required. I think there must be something else going on that isn’t visible in the snippets you included here.

Hi @ apparentlymart, please allow me to deliver more details, indeed my explanation was lacking,

###Terraform provider is Azure, what I’m intending to do? build a VM and passing the User/Password via variables to avoid expose the secrets, or write them into the Main.tf file (I have done this, and has worked for me fine, but is not a good security practice)

###main.tf, here is the relevant content that interacts with the User/Passwords I’m trying to pass to the VM to allow me to administer it:

resource "azurerm_network_interface" "nic_poc" {
  count               = 1
  name                = "nic_test_persistent${count.index}"
  location            = "North Europe"
  resource_group_name = local.rg.name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = data.terraform_remote_state.my_azure_dev.outputs.org_dev.subnet.northeurope.main.subnets["dev1-XX.XXX.XXX.X_XX"].id
    private_ip_address_allocation = "Dynamic"
  }
}
resource "azurerm_windows_virtual_machine" "vm_persistent" {
  count               = 1
  name                = "vm-persistent${count.index}"
  resource_group_name = local.rg.name
  location            = "North Europe"
  size                = "Standard_D4_v3"

# Here my variables for User/Password
  admin_username      = "var.admin_username"
  admin_password      = "var.admin_password"
  network_interface_ids = [
    element(azurerm_network_interface.nic_poc.*.id, count.index)
  ]

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2019-Datacenter"
    version   = "latest"
  }
 
}

###terraform.tfvars, here declaring the value of the variable because it what I have understood from several examples (maybe misunderstood them)

###terrafrom.tfvars, here declaring the value for these variables:
TF_VAR_admin_username = "adminuser"
TF_VAR_admin_password = "MySuperPassword"

###variables.tf, here declaring the variables without value because don’t know if I can declare it here and how

variable "admin_username" {
    type = string
}

variable "admin_password" {
    type = string
}

###Error

Error: creating Windows Virtual Machine "vm-persistent0" (Resource Group "nXXX-XXX-dev1-org-dev-XX"): compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=0 -- Original Error: Code="InvalidParameter" Message="The supplied password must be between 8-123 characters long and must satisfy at least 3 of password complexity requirements from the following:\r\n1) Contains an uppercase character\r\n2) Contains a lowercase character\r\n3) Contains a numeric digit\r\n4) Contains a special character\r\n5) Control characters are not allowed" Target="adminPassword"

Does your password actually meet all of these requirements ( MySuperPassword)

The supplied password must be between 8-123 characters long and must satisfy at least 3 of password complexity requirements from the following:

  1. Contains an uppercase character
  2. Contains a lowercase character
  3. Contains a numeric digit
  4. Contains a special character
  5. Control characters are not allowed

Hi @aram yes it does because it has worked when added it directly to the Main.tf file,

I have place that generic you saw just avoid share publically the real one, in reallity our password is more like this shown below:

OurP@**w0rd1998#

Thanks for taking the time to aswering to this thread,

What do you think is missing or not correct in the declaration of the variables and their values?
Should they be in separeted files, variables.tf and terraform.tfvar respectively, or is there a way to declare the variable and its value at once in a single place/way?

I’m no expert, comparably only been using terrform for a short time but have you tried A) tagging it as sensitive?
B) with a -var-file=myvars.tfvars rather than env variable? Just increase the special characters are getting whacked in the terminal?

Hi @aram ,

The option B) is already been mention in my explanation, please see that part added to this reply below:

###variables.tf, here declaring the variables without value because don’t know if I can declare it here and how

###terrafrom.tfvars, here declaring the value for these variables:
TF_VAR_admin_username = "adminuser"
TF_VAR_admin_password = "MySuperPassword"

Hi @dranenko,

I think the problem in your configuration is the way you tried to refer to the variables:

  admin_username      = "var.admin_username"
  admin_password      = "var.admin_password"

You’ve written these two reference-like strings in quotes, and so Terraform thinks you want to set the password to literally “var.admin_password”, not to the contents of that variable. Thankfully the password policy caught this mistake because this reference doesn’t contain all of the required characters; if that policy weren’t there then you could’ve ended up with the admin password set to a well-known string in the configuration! :grimacing:

To fix this, write these as normal references rather than quoted strings:

  admin_username      = var.admin_username
  admin_password      = var.admin_password
1 Like

Master of Masters you are right, did test that change and is working now,

Thanks, finally I have learned how to securely pass variables instead of exposing in the Main.tf file the credentials (User/Password)