Terraform Integrated with Chef

Community,

I am using the following provisioner code to run a command to trigger chef to run on the remote node via my chef workstation.

#Jumpstarts the bootstrapping of the remote server.
 provisioner "local-exec" {
   command = "knife bootstrap windows winrm '${aws_instance.[SERVER_NAME].private_ip}' -y -N '[NODE_NAME]' -x '.\\[USER_NAME]' -P ''${rsadecrypt(self.password_data,file("./[PEM_FILE_NAME].pem"))}'' --run-list 'role[ROLE_NAME]' --bootstrap-install-command 'msiexec /i http://[PATH_TO_MSI]/chef-client-14.5.33-1-x64.msi'"
 }

I know the command works via command line but I can not figure out how to pass the following with double quotes as it I’ll cause the variable to no longer be highlighted.

''${rsadecrypt(self.password_data,file("./[PEM_FILE_NAME].pem"))}''

Note... of the variable isn’t passed with the double quotes this will not work for me. So please tell me how to pass this with double quotes.

Many thanks,

You would use standard bash escaping sequence \", but do consider the following options:
1- The terraform Chef provisioner. I hate it and it doesn't scale well, but it's all TF
2- Use cloud-init as described here: https://docs.chef.io/install_bootstrap.html#unattended-installs this is my preferred method and it's compatible with fancier setups like autoscaling groups

Any clue what I am doing wrong?

My CODE:

provisioner "chef" {
    connection {
        type     = "winrm"
        user     = "Administrator"
        password = "${rsadecrypt(self.password_data,file("./[MY_PEM_FILE].pem"))}"
      }

    environment     = "_default"
    run_list        = ["role::[ROLE_NAME]"]
    node_name       = "[NODE_NAME]"
    server_url      = "[CHEF_SERVER_URL]"
    recreate_client = true
    user_name       = "[CHEF_SERVER_USER_NAME]"
    user_key        = "${file("./[MY_PEM_FILE].pem")}"
    version         = "14.4.56"
    ssl_verify_mode = ":verify_none"
    no_proxy        = ["[MY_IPs]","[MY_IPs]","[MY_IPs]"]
  }

ERROR:

module.default.aws_instance.[MY_REMOTE_NODE] (chef): Connecting to remote host via WinRM...
module.default.aws_instance.[MY_REMOTE_NODE] (chef):   Host: [MY_REMOTE_NODE_IP]
module.default.aws_instance.[MY_REMOTE_NODE] (chef):   Port: 5985
module.default.aws_instance.[MY_REMOTE_NODE] (chef):   User: Administrator
module.default.aws_instance.[MY_REMOTE_NODE] (chef):   Password: true
module.default.aws_instance.[MY_REMOTE_NODE] (chef):   HTTPS: false
module.default.aws_instance.[MY_REMOTE_NODE] (chef):   Insecure: false
module.default.aws_instance.[MY_REMOTE_NODE] (chef):   NTLM: false
module.default.aws_instance.[MY_REMOTE_NODE] (chef):   CACert: false
module.default.aws_instance.[MY_REMOTE_NODE]: Still creating... (18m51s elapsed)

Error: Error applying plan:

1 error(s) occurred:

* module.default.aws_instance.[MY_REMOTE_NODE]: timeout - last error: http response error: 401 - invalid content type

Terraform does not automatically rollback in the face of errors.
Instead, your Terraform state file has been partially updated with
any resources that successfully completed. Please address the error
above and apply again to incrementally change your infrastructure.

I keep getting this ERROR. Any clues where I should look to fix this?

it looks like you're trying to pass the Windows admin password from a PEM file, which is not only unusual but also not supported as is. You would need to somehow extract the key's value to a local and reference tht using TF interpolation or something such, but those are questions better asked on TF's Gitter.

Try setting the password directly (clear-text) and work twoards stronger security once you have a basic setup going.