Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to provision an custom image and make use of user_data #18

Open
jlarfors opened this issue Nov 22, 2021 · 4 comments
Open

How to provision an custom image and make use of user_data #18

jlarfors opened this issue Nov 22, 2021 · 4 comments
Labels
enhancement New feature or request

Comments

@jlarfors
Copy link

Hello, I am building a custom image using Packer that I later want to provision with Terraform and make use of user_data when provisioning with Terraform.

However, seems the user_data has no effect when provisioning with Terraform.

Any way to get this to work?

Packer

We have something liek this for packer:

packer {
    required_plugins {
        upcloud = {
            version = "v1.2.0"
            source = "github.com/UpCloudLtd/upcloud"
        }
    }
}

source "upcloud" "vault" {
  username = "${var.username}"
  password = "${var.password}"
  zone = "fi-hel1"
  storage_name = "Debian GNU/Linux 11"
  template_prefix = "deb-hashi-vault"
}

build {
  sources = ["source.upcloud.vault"]
  // ... more provisioning stuff here
}

Terraform

And something liek this with Terraform:

resource "upcloud_network" "private_network" {
  name = "example_private_net"
  zone = "fi-hel1"

  # router = upcloud_router.example_router.id

  ip_network {
    address            = "10.0.0.0/24"
    dhcp               = true
    dhcp_default_route = false
    family             = "IPv4"
    gateway            = "10.0.0.1"
  }
}

resource "upcloud_server" "vault" {
  hostname = "vault-server"
  zone     = "fi-hel1"
  plan     = "1xCPU-1GB"

  template {
    # uuid of packer built image
    storage = var.custom_image
    size = 25
  }


  network_interface {
    type = "public"
  }

  // Simple user_data test
  user_data = "#!/bin/bash\ntouch /tmp/test.txt"
}
@Darep
Copy link
Member

Darep commented Nov 22, 2021

user_data does not work in a custom image unless you have specifically implemented it into your custom image. E.g. if you use our public template for Debian, user_data should work normally.

Are you handling the user_data field somehow in your image, or is your image based on one of our public templates by any chance? If you need to implement this into your custom image, you could for example try with cloud-init & our metadata API. UpCloud has a small tutorial for the metadata API: https://upcloud.com/community/tutorials/upcloud-metadata-service/ . The metadata API needs to be enabled on server creation.

Let me know if this helps 😊

@jlarfors
Copy link
Author

Thanks for the reply.

The base image for packer is one of your public templates Debian GNU/Linux 11, so this should work, right?
Do you need anything to reproduce this? I think my example should be pretty complete to reproduce it.

I also tested cloud-init with one of your public Debian images but wasn't sure what would need to be configured to make that work... It would be preferable if cloud-init could be "enabled" when using packer but I don't know the internals of all this, only have experience using cloud-init with other clouds. So if you have some pointers that'd be awesome!

@Darep
Copy link
Member

Darep commented Nov 23, 2021

Ahh, yeah, at least I was under the impression that it should work 😲 Weird! 😄 I will ask some UpCloudians if they know what's up & if someone could investigate this more deeply.

@ka-myl
Copy link

ka-myl commented Nov 30, 2021

Hi @jlarfors

user_data is not exactly supported for custom images. However if the custom image is based on UpCloud official template, you could get this to work by:

  1. Installing (or updating) cloud-init v21.1+
  2. Removing /var/lib/cloud directory (to make sure cloud-init runs on the next boot)

The caveat with Debian 11 template is that there isn't a recent-enough cloud-init version available in main repository, so to get it working you might need to built cloud-init from source, or install from testing (which might have some side effects, so it's not really optimal production setup).
The following packer config worked for me:

packer {
    required_plugins {
        upcloud = {
            version = "v1.2.0"
            source = "github.com/UpCloudLtd/upcloud"
        }
    }
}

source "upcloud" "vault" {
  username = "${var.username}"
  password = "${var.password}"
  zone = "fi-hel1"
  storage_name = "Debian GNU/Linux 11"
  template_prefix = "vault-image"
}

build {
  sources = ["source.upcloud.vault"]

  provisioner "shell" {
    inline = [
      "cp /etc/apt/sources.list /etc/apt/sources.list.bak",
      "echo 'deb http://deb.debian.org/debian/ testing main' >> /etc/apt/sources.list",
      "apt-get update",
      "DEBIAN_FRONTEND=noninteractive apt -y install cloud-init=21.4-1",
      "rm -rf /var/lib/cloud",
      "cp -f /etc/apt/sources.list.bak /etc/apt/sources.list",
      # ... more provisioning stuff here
    ]
  }
}

And then with Terraform:

resource "upcloud_server" "vault" {
  hostname = "vault-server"
  zone     = "fi-hel1"
  plan     = "1xCPU-1GB"
  metadata = true

  template {
    # Custom image based on Debian 11
    storage = var.custom_image
    size = 25
  }

  network_interface {
    type = "public"
  }

  login {
    keys = [
      "my-ssh-pub-key"
    ]
  }

  // Simple user_data test
  user_data = "#!/bin/bash\ntouch /tmp/test.txt"
}

Note that metadata has to be allowed for the server for this to work.

Please also note that default cloud-init config disables root login and creates a debian user instead. So to be able to log into the server properly, you might need to tweak the /etc/cloud/cloud.cfg file for your custom image. I took a shortcut and set the SSH key via Terraform login block (which just works for debian user, but is not exactly optimal).

I hope this clears things out a bit, let us know if you have any other questions :)

@thevilledev thevilledev added the enhancement New feature or request label Jan 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants