pkaramol
pkaramol

Reputation: 19352

terraform: Add an OS user with a given public key

I have created an EC2 instance on AWS using terraform;

What I want is to add a user in the OS level and provide a particular key to be added in its ~/.ssh/authorized_keys file.

The aws_instance documentation does not seem to list this functionality.

Is there a way to go about this?

edit: I think a way to do this is via the remote-exec provisioner, but then again since I have already created my ec2 resource I need a way to force-run this;

Upvotes: 11

Views: 16802

Answers (3)

jobwat
jobwat

Reputation: 9223

As already mentioned, best is to bake such config in the AMI.

But for some temporary/dev work, another way is to use the EC2 UserData block:

data "local_file" "public_ssh_key" {
  filename = "/path/to/.ssh/id_rsa.pub"
}

resource "aws_instance" "sample" {
  ...
  user_data = <<-EOF
    #!/bin/bash
    sudo -u ubuntu bash -c 'echo "${data.local_file.public_ssh_key.content}" >> ~/.ssh/authorized_keys'
    EOF
  ...
}

Upvotes: 1

pkaramol
pkaramol

Reputation: 19352

Answer given by @Brandon Miller seems to be nice, I ended up with the following (not very elegant, I must admit):

  provisioner "remote-exec" {
    inline = [
        "sudo adduser --disabled-password --gecos '' myuser",
        "sudo mkdir -p /home/myuser/.ssh",
        "sudo touch /home/myuser/.ssh/authorized_keys",
        "sudo echo '${var.MY_USER_PUBLIC_KEY}' > authorized_keys",
        "sudo mv authorized_keys /home/myuser/.ssh",
        "sudo chown -R myuser:myuser /home/myuser/.ssh",
        "sudo chmod 700 /home/myuser/.ssh",
        "sudo chmod 600 /home/myuser/.ssh/authorized_keys",
        "sudo usermod -aG sudo myuser"
   ]

    connection {
     user     = "ubuntu"
    }

  }

Upvotes: 10

Brandon Miller
Brandon Miller

Reputation: 5065

Following up on comments and edits, what you are looking for might look like this:

resource "aws_instance" "default" {
  ...
  provisioner "remote-exec" {
    inline = [
      "sudo useradd someuser"
    ]

    connection {
      type        = "ssh"
      user        = "ubuntu"
      private_key = "${file("yourkey.pem")}"
    }
  }

  provisioner "file" {
    source      = "authorized_keys"
    destination = "/home/someuser/.ssh/authorized_keys"

    connection {
      type        = "ssh"
      user        = "ubuntu"
      private_key = "${file("yourkey.pem")}"
    }
  }

  provisioner "remote-exec" {
    inline = [
      "sudo chown someuser:someuser /home/someuser/.ssh/authorized_keys",
      "sudo chmod 0600 /home/someuser/.ssh/authorized_keys"
    ]

    connection {
      type        = "ssh"
      user        = "ubuntu"
      private_key = "${file("yourkey.pem")}"
    }
  }
  ...
}
  • Create the user
  • Upload your authorized keys file
  • Set the appropriate permissions on the file for the user

You could also do this all in one remote-exec depending on how you want to handle setting up the authorized_keys file

Upvotes: 10

Related Questions