12

My question is similar to this git hub post, but unfortunately it is unsolved:

https://github.com/hashicorp/terraform/issues/550

I want a simple way to give sudo privileges to the commands run in the provisioner "remote-exec" { } block of my terraform scripts.

I am coming from an ansible background that has the sudo: yes option that allows any commands ansible runs to run commands with sudo privileges when using the --ask-sudo-pass optional in my ansible-playbook run commands. I would like to do something like that in the provisioner "remote-exec" block of my terraform script.

Here is the provisioner "remote-exec" block I want to run:

  provisioner "remote-exec" {
    inline = [
      "sudo apt-get update",
      "sudo apt-get install -y curl"
    ]
  }

When I run this in my terraform apply I see the following lines appear in the output of this command:

openstack_compute_instance_v2.test.0 (remote-exec): [sudo] password for myUserName:
openstack_compute_instance_v2.test.1 (remote-exec): [sudo] password for myUserName:
openstack_compute_instance_v2.test.2 (remote-exec): [sudo] password for myUserName:

Then it just gives me an infinite number of these:

openstack_compute_instance_v2.test.0: Still creating... 
openstack_compute_instance_v2.test.1: Still creating... 
openstack_compute_instance_v2.test.2: Still creating... 

So how do I fix this and let terraform run sudo commands?

Note: The connection for my provisioner "remote-exec" block cannot be root, so even though that would be a simple solution its not what I can use.

Alex Cohen
  • 5,596
  • 16
  • 54
  • 104

3 Answers3

17

The answer was to use the following syntax in my first sudo command:

"echo yourPW | sudo -S someCommand" 

This bypasses the sudo password prompt and enters the password directly into the command. I already had my sudo password as a variable "${var.pw}" so running my sudo commands was the simple matter of changing my first command to:

  provisioner "remote-exec" {
    inline = [
      "echo ${var.pw} | sudo -S apt-get update",
      "sudo apt-get install -y curl"
    ]
  }
Alex Cohen
  • 5,596
  • 16
  • 54
  • 104
  • Won't this print passwords to the log? Also, it seems risky that you expect the second `sudo` to not ask for password because the first run caches it. – eternaltyro Mar 26 '19 at 21:55
  • 1
    It might. Honestly I haven't touched terraform in years. If you have a better solution, post it! – Alex Cohen Mar 26 '19 at 22:38
3

What about:

echo ${var.pw} | sudo -S -k apt-get update

-k means to ignore cached credentials to force sudo to always ask. This is for consistent behavior.

https://superuser.com/q/67765

double-beep
  • 5,031
  • 17
  • 33
  • 41
Paesano19
  • 31
  • 3
  • I really wanted to comment on Alex Cohen's answer but can't since I'm a new member and don't have 50 reputation, so posting this separate. – Paesano19 May 23 '19 at 14:22
  • 2
    Nope. Adding an answer is the appropriate way, since you have a different solution. – double-beep May 23 '19 at 14:24
3

In case of EC2 instance, its difficult to handle that with password. I just a gave try to below solution and it worked.

Step 1 : Put all of your commands in script.sh file in your current workspace/working directory

Step 2 : Instead of inline argument, use script argument and simply include below lines of code in resource block.

provisioner "file" {
    source      = "script.sh"
    destination = "/tmp/script.sh"
  }

  provisioner "remote-exec" {
    inline = [
      "chmod +x /tmp/script.sh",
      "sudo /tmp/script.sh args",
    ]
  }

With this solution, terraform will copy the script.sh containing all the shell commands need to be executed at /tmp location of server and it will execute the file with sudo permissions.Below is the reference link.

https://www.terraform.io/docs/provisioners/remote-exec.html

anuradha
  • 31
  • 2