0

I am using cloud-init to run commands on my instance using user-data. I want to create password for jupyter notebook that I want to start as systemd.

this is my terraform main.tf

resource "oci_core_instance" "jupyterlab_instance" {
  metadata = {
    ssh_authorized_keys = var.ssh_public_key_file
    user_data           = base64encode(file(var.bootstrap_file) "123456")
  }

bootstrap.sh


function systemd_jupyter_instance() {
  echo "setting up systemd for jupyter at localhost:8888"

#  password=$(python -c "from IPython.lib.security import passwd; print(passwd('PASS'))")
cat <<EOF > /etc/systemd/system/jupyterInst.service
[Unit]
Description=Jupyter instance

[Service]
User=opc
Group=opc
WorkingDirectory=/etc/jupyter/
ExecStart=/usr/local/bin/jupyter-notebook --ip=0.0.0.0 --port 8888 --NotebookApp.password=$1

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl is-active --quiet jupyterInst && sudo systemctl stop jupyterInst
sudo systemctl enable --now jupyterInst
sudo systemctl status jupyterInst

}

function main() {
  systemd_jupyter_instance
}

main

I have tried this and I cannot have space while passing user_data. I have tried remote-exec provisioner but having issues connecting to my instance because I will have to pass my private key in .tf which I want to avoid.

Any help is appreciated. Thanks

Marko E
  • 13,362
  • 2
  • 19
  • 28
masterfly
  • 861
  • 4
  • 11
  • 24
  • Typically the shebang `#!/bin/bash` is what tells cloud-init to process the user data as a script. Your function takes an arg but you are not passing an arg. I think this is what you're looking for: https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/file – jordanm Jul 05 '22 at 16:52
  • Which value do you want to pass, `123456`? And where would it be used in the script, i.e., what needs to consume that value? – Marko E Jul 05 '22 at 17:05
  • yes, `123456` is the value that I need to pass. it will be used to configure jupyter instance password in bash script. – masterfly Jul 05 '22 at 17:21
  • 1
    Aside: `function funcname() {` merges the POSIX-standardized syntax `funcname() {` and the 1980s-ksh syntax `function funcname {` in a way that's incompatible with **both** POSIX sh and 1980s ksh (and also semantically compatible with ksh, which changes how `typeset` works inside functions based on the declaration mode). See also https://wiki.bash-hackers.org/scripting/obsolete – Charles Duffy Jul 05 '22 at 17:24

1 Answers1

2

In this case I would suggest using the templatefile built-in function [1]. In order to do that, there has to be a slight modification in both the resource and the user data script. In the resource block, it has to be changed to:

resource "oci_core_instance" "jupyterlab_instance" {
  metadata = {
    ssh_authorized_keys = var.ssh_public_key_file
    user_data           = base64encode(tamplatefile(var.bootstrap_file, 
       password = "123456"
   ))
  }

Then, in the file itself, you would have to remove $1 and add the following:

#!/bin/bash

systemd_jupyter_instance() {
  echo "setting up systemd for jupyter at localhost:8888"

#  password=$(python -c "from IPython.lib.security import passwd; print(passwd('PASS'))")
cat <<EOF > /etc/systemd/system/jupyterInst.service
[Unit]
Description=Jupyter instance

[Service]
User=opc
Group=opc
WorkingDirectory=/etc/jupyter/
ExecStart=/usr/local/bin/jupyter-notebook --ip=0.0.0.0 --port 8888 --NotebookApp.password=${password}

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl is-active --quiet jupyterInst && sudo systemctl stop jupyterInst
sudo systemctl enable --now jupyterInst
sudo systemctl status jupyterInst

}

main() {
  systemd_jupyter_instance
}

main

Usually, the filename would have a .tpl extension to indicate it is a template.

EDIT: As per comments, added the shebang at the start of the template.


[1] https://www.terraform.io/language/functions/templatefile

Marko E
  • 13,362
  • 2
  • 19
  • 28
  • thanks @marko this was the closest answer that helped. I got it working by defining templatefile in the local ``` bootstrap_configure_file = templatefile(var.bootstrap_file, { jp_password = var.jp_password }) ``` in compute: ``` metadata = { ssh_authorized_keys = var.ssh_public_key_file user_data = base64encode(local.bootstrap_configure_file) } ``` – masterfly Jul 06 '22 at 19:43