Skip to content

feat: Added action to write Cloud Init volumes from hardware data#164

Open
appkins wants to merge 5 commits intotinkerbell:mainfrom
tinkerbell-community:main
Open

feat: Added action to write Cloud Init volumes from hardware data#164
appkins wants to merge 5 commits intotinkerbell:mainfrom
tinkerbell-community:main

Conversation

@appkins
Copy link
Copy Markdown

@appkins appkins commented Nov 19, 2025

Description

Adds a workflow action to write user data, meta-data and user-data to a cloud init volume - to be consumed by nocloud provisioning.

Note: The hardware data is templated - meaning it does not rely on a specific version of Tinkerbell or the CRDs. Instead, it plays nicely with the workflow template design.

Example

The following template fully implements the TalosControlPlane requirements using predictable image paths. No additional configuration is needed to pair Tinkerbell and Talos bootstrap/control plane.

version: "0.1"
name: talos-install-template
global_timeout: 9800
tasks:
  - name: "install-talos"
    worker: "{{.device_1}}"
    volumes:
      - /dev:/dev
      - /dev/console:/dev/console
      - /lib/firmware:/lib/firmware:ro
    actions:
      - name: "stream talos nocloud image"
        image: quay.io/tinkerbell/actions/image2disk:latest
        timeout: 9600
        environment:
          DEST_DISK: {{ index .Hardware.Disks 0 }}
          # Use the nocloud platform image instead of metal
          IMG_URL: "https://factory.talos.dev/image/{{ .Hardware.Metadata.Instance.OperatingSystem.Slug }}/{{ .Hardware.Metadata.Instance.OperatingSystem.Version }}/nocloud-{{ eq (index .Hardware.Interfaces 0).DHCP.Arch "aarch64" | ternary "arm64" "amd64" }}.raw.zst"
          COMPRESSED: "true"

      - name: "create cidata partition and write files"
        image: ghcr.io/tinkerbell-community/actions/cidataio:latest
        timeout: 300
        environment:
          DEST_DISK: {{ index .Hardware.Disks 0 }}
          META_DATA: |
            hostname: {{ coalesce (index .Hardware.Interfaces 0).DHCP.Hostname ((index .Hardware.Interfaces 0).DHCP.MAC | replace ":" "-" | printf "talos-%s") }}
            local-hostname: {{ coalesce (index .Hardware.Interfaces 0).DHCP.Hostname ((index .Hardware.Interfaces 0).DHCP.MAC | replace ":" "-" | printf "talos-%s") }}
            instance-id: {{ coalesce (index .Hardware.Interfaces 0).DHCP.Hostname ((index .Hardware.Interfaces 0).DHCP.MAC | replace ":" "-" | printf "talos-%s") }}
            provider-id: {{ coalesce (index .Hardware.Interfaces 0).DHCP.Hostname ((index .Hardware.Interfaces 0).DHCP.MAC | replace ":" "-" | printf "talos-%s") | printf "tinkerbell://tinkerbell/%s" }}
          NETWORK_CONFIG: |
            version: 2
            ethernets:
              {{- range $index, $iface := .Hardware.Interfaces }}
              {{ coalesce $iface.DHCP.IfaceName (printf "eth%d" $index) }}:
                match:
                  macaddress: "{{ $iface.DHCP.MAC }}"
                dhcp4: true
                dhcp6: false
                nameservers:
                  addresses:
                    {{- range $dns := $iface.DHCP.NameServers }}
                    - {{ $dns }}
                    {{- end }}
              {{- end }}
          USER_DATA: |
            {{- .Hardware.UserData | trim | nindent 12 }}

      - name: "reboot"
        image: ghcr.io/jacobweinstock/waitdaemon:latest
        timeout: 90
        pid: host
        environment:
            IMAGE: alpine
            WAIT_SECONDS: 10
        volumes:
          - /var/run/docker.sock:/var/run/docker.sock
        command: ["reboot"]

Fixes: #

How Has This Been Tested?

Extensively. Using it in a real world environment to write TalosConfig to a fleet of edge devices.

How are existing users impacted? What migration steps/scripts do we need?

No impact, new action.

Checklist:

This pull request introduces a new Tinkerbell action called cidataio, which automates the creation of a cloud-init (cidata) partition and writes configuration files to it. The changes include adding the new action to the build system, updating CI/CD workflows, and providing documentation and implementation for cidataio. The most important changes are grouped below:

Addition of the cidataio Action:

  • Added a new cidataio action, including its implementation in cidataio/main.go, which creates a cidata partition, formats it, mounts it, and writes cloud-init data files from environment variables.
  • Added a Dockerfile for cidataio to build and package the action as a container image.
  • Added documentation for cidataio in cidataio/README.md, describing its usage, environment variables, and example workflow.

Build System and Workflow Updates:

  • Updated the Makefile to include cidataio in the list of buildable actions and made the container repository configurable.
  • Changed the build platform for actions in the Makefile from linux/amd64 to linux/arm64.

CI/CD Pipeline Enhancements:

  • Updated .github/workflows/ci.yml and .github/workflows/release.yml to include cidataio in the matrix of actions to build and release. [1] [2]
  • Improved the release workflow to dynamically select the container registry (Quay or GHCR) based on available credentials and set appropriate permissions and environment variables for publishing.
    I have:
  • updated the documentation and/or roadmap (if required)
  • added unit or e2e tests
  • provided instructions on how to upgrade

Signed-off-by: appkins <nbatkins@gmail.com>
Signed-off-by: appkins <nbatkins@gmail.com>
@appkins appkins mentioned this pull request Nov 19, 2025
3 tasks
@appkins appkins force-pushed the main branch 7 times, most recently from 389a905 to 072f412 Compare January 15, 2026 01:35
Signed-off-by: appkins <nbatkins@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant