lxc / terraform-provider-incus

Incus provider for Terraform/OpenTofu
https://linuxcontainers.org/incus
Mozilla Public License 2.0
35 stars 8 forks source link

Add support for `incus exec` to `incus_instance` resource #27

Closed matifali closed 1 month ago

matifali commented 5 months ago

It would be nice to have support for incus exec in the incus_instance resource.

maveonair commented 5 months ago

Would it be possible for you to post an example of what you want to do with it and what the syntax might look like?

stgraber commented 1 month ago

Closing due to no response.

In general I expect Terraform to be used for things that can be checked against the specification, running commands isn't really a good fit there. Something like an Ansible playbook tends to work best for that kind of use case.

tregubovav-dev commented 3 weeks ago

Yeh... my comment is coming late. (I've just migrated from LXD to Incus) Here is a discussion in terraform-lxd related to implementation exec section in the instance plugin: https://github.com/terraform-lxd/terraform-provider-lxd/pull/386

Using exec functionality in open-tofu/terraform plugin can significantly simplify deployments using the single tool (open-tofu or terraform) without tricks.

Please see for the simple scenario (as an example): You need to deploy set of instances, and install and configure specific services on them. For example - deploy DNS cache farm on top of Alpine containers which using unmanaged incus network. Generic steps are:

These steps can be automated with using cloud-init, or incus command-line tool. Both of them allows to run commands inside the container. This is good approach; however it's has serious drawback, it's maintenance/support costs comparing to open-tofu/terraform desired state configurations. Having exec resource will allow to deploy such configurations in one shot. exec resource may looks like below

resource "incus_instance" "instance" {
  name = "instance_name"
  ...
}

resource "incus_file" "instance_dnsmasq_conf" {
  target_path="/etc/dnsmasq.conf"
  content="<content of config>"
}
resource "incus_exec" "instance_pre" {
  instance = incus_instance.instance.name
  commands = [
    ["apk", " install", "dnsmasq"]
    ["rc-update", "add", "dnsmasq"]
  ]
}

resource "incus_exec" "instance_post" {
  instance = incus_instance.instance.name
  commands = [
    ["service", "dnsmasq", "start"]
  ]
  depends_on = [incus_exec.instance_pre, incus_file.instance_dnsmasq_conf]
}

P.S. Using cloud-init images add additional memory footprint. cloud-init require at least 90MB RAM (depending on distribution) to run successfully on boot. This may be significant restriction for incus/lxd clusters running on low cost SBCs.