Incus Terraform

Enable Incus remote API authentication
http://www.panticz.de/incus

Terraform main.tf

terraform {
  required_providers {
    incus = {
      source = "lxc/incus"
    }
  }
}
 
provider "incus" {
  # generate_client_certificates = true
  # accept_remote_certificate    = true
 
  remote {
    name    = "10.0.1.104"
    scheme  = "https"
    address = "10.0.1.104"
    token   = "xxxxxxxxxxxxxxxxxxxxxxxxxx"
    default = true
  }
}
 
data "template_file" "user_data" {
  template = <<EOF
#cloud-config
package_update: true
packages:
  - nginx
runcmd:
  - sudo systemctl stop unattended-upgrades
  - sudo apt purge -y unattended-upgrades
EOF
}
 
resource "incus_instance" "instance_1" {
  name             = "u2404"
  description      = "Terraform Incus test container"
  image            = "images:ubuntu/24.04/cloud"
  profiles         = ["default"]
  wait_for_network = true
 
  config = {
    "boot.autostart"       = true
    "limits.cpu"           = 4
    "cloud-init.user-data" = data.template_file.user_data.rendered
  }
 
  device {
    name = "http"
    type = "proxy"
    properties = {
      listen = "tcp:0.0.0.0:80"
      connect = "tcp:127.0.0.1:80"
    }
  }
}

Deploy

Mosquitto MQTT server

Install
https://www.howtoforge.de/anleitung/so-installierst-du-mosquitto-mqtt-server-unter-ubuntu-22-04/

sudo apt-get install -y curl gnupg2 wget git apt-transport-https ca-certificates software-properties-common
sudo add-apt-repository -y ppa:mosquitto-dev/mosquitto-ppa
sudo apt install mosquitto mosquitto-clients -y
 
sudo mosquitto_passwd -c -b /etc/mosquitto/passwd foo pass1234
# todo sudo
cat <<EOF> /etc/mosquitto/conf.d/default.conf
listener 1883
password_file /etc/mosquitto/passwd
EOF
chmod a+r /etc/mosquitto/passwd
 
sudo systemctl restart mosquitto

Debug MQTT
http://mqtt-explorer.com/
https://snapcraft.io/install/mqtt-explorer/ubuntu#install

sudo snap install mqtt-explorer

Tasmota Smart Meter Interface

ESP8266 / ESP32 Tasmota images and decumentation
https://ottelo.jimdofree.com/stromz%C3%A4hler-auslesen-tasmota/#Downloads
https://www.wispr-shop.de/produkt/wifi-ir-schreib-lesekopf-diy-set/

Smart Meter Interface configruation scripts
https://tasmota.github.io/docs/Smart-Meter-Interface/#emh-ehz-generation-k-sml

>D
>B
 
=>sensor53 r
>M 1
+1,3,s,0,9600,
1,77070100010800ff@1000,Total consumption,kWh,total_in,2
1,77070100020800ff@1000,Total feed-in,kWh,total_out,2
1,77070100100700ff@1,Power,W,power_curr,0
#

Tasmota Diagramme
https://github.com/ottelo9/tasmota-sml-script/

Tasmota Script Language Support
https://marketplace.visualstudio.com/items?itemName=StefanoBertini.tasmota-script-support#Automatic-script-upload

Incus

Prerequisits

# ZFS (optional)
sudo apt install -y zfsutils-linux
sudo lvcreate --name storage --size 100G ubuntu-vg
sudo zpool create incus /dev/ubuntu-vg/storage
sudo zpool set autotrim=on incus
sudo zfs create incus/storage

Incus installation
https://linuxcontainers.org/incus/docs/main/installing/

sudo apt install -y incus incus-tools bash-completion
incus completion fish

Incus configuration
https://linuxcontainers.org/incus/docs/main/howto/initialize/#configuration-format

cat <<EOF | incus admin init --preseed
config:
  core.https_address: 10.0.1.1:9999
  images.auto_update_interval: 15
 
storage_pools:
# default
- name: data
  driver: zfs
  config:
    source: incus/storage
 
# Network devices
networks:
- name: incusbr0
  type: bridge
  config:
    ipv4.address: auto
    ipv6.address: none
 
# Profiles
profiles:
- name: default
  description: "Default profile"
  config:
    limits.memory: 8GiB
  devices:
    disk:
      path: /
      pool: data
      type: disk
    nic:
      name: eth0
      nictype: bridged
      parent: incusbr0
      type: nic
EOF
 
incus storage list
incus network list
incus profile show default

Create instance

Designate as authenticator for Lets Encrypt

Prerequisites
Install OpenStack CLI client (OSC)
http://www.panticz.de/osc

OpenStack Application credentials
~/.config/openstack/clouds.yaml

Generate Lets Encrypt certificate

sudo apt install -y certbot
 
pyenv activate osc
pip install python-designateclient certbot-dns-openstack zope
 
# list available zones
openstack zone list
 
# Create letsencrypt directory
mkdir ~/letsencrypt
 
# Request wildcard certificate
DOMAIN=example.com
certbot -a dns-openstack certonly \
    --agree-tos \
    --register-unsafely-without-email \
    --work-dir ~/letsencrypt/work \
    --config-dir ~/letsencrypt/etc \
    --logs-dir ~/letsencrypt/log \
    --dns-openstack-propagation-seconds 60 \
    -d *.${DOMAIN}
#    -d *.example.com,example.com
 
# List certificates
ls -l ~/letsencrypt/etc/archive/*/*

DEBUG (second terminal)

watch -n1 openstack recordset list example.com

Links
https://docs.binero.com/guides/designate-as-authenticator-for-lets-encrypt.html
https://letsencrypt.org/docs/challenge-types/

Create OpenStack DualStack or IPv6 only VM

# Create router
openstack router create test-router1 \
  --centralized \
  --ha \
  --external-gateway public
 
# Show available tenant IPv6 subnet
openstack subnet pool list --share | grep tenant-subnet-pool-v6
 
# Create network
openstack network create test-network1
 
# DUAL-STACK: Create IPv4 subnet (skip for IPv6 only)
openstack subnet create test-subnet1-ipv4 \
  --network test-network1 \
  --subnet-range 10.11.12.0/24
 
# DUAL-STACK: Attach IPv4 subnet to router (skip for IPv6 only)
openstack router add subnet test-router1 test-subnet1-ipv4
 
# Create IPv6 subnet
openstack subnet create test-subnet1-ipv6 \
  --network test-network1 \
  --ip-version 6 \
  --subnet-pool tenant-subnet-pool-v6 \
  --prefix-length 64 \
  --ipv6-ra-mode dhcpv6-stateless \
  --ipv6-address-mode dhcpv6-stateless
 
# Attach IPv6 subnet to router
openstack router add subnet test-router1 test-subnet1-ipv6
 
# OPTINAL: allow access from outside
SECURITY_GROUP=test-secgroup
openstack security group create ${SECURITY_GROUP}
 
# DUAL-STACK: allow access to Floating FIP from outside (skip for IPv6 only)
openstack security group rule create ${SECURITY_GROUP} --ethertype IPv4 --protocol icmp --ingress --remote-ip 0.0.0.0/0
openstack security group rule create ${SECURITY_GROUP} --ethertype IPv4 --protocol icmp --egress --remote-ip 0.0.0.0/0
openstack security group rule create ${SECURITY_GROUP} --ethertype IPv4 --protocol tcp --dst-port 22 --remote-ip 0.0.0.0/0