graphiant.naas.graphiant_device_lifecycle module – Manage device lifecycle state and software upgrades/rollback

Note

This module is part of the graphiant.naas collection (version 26.10.0).

You might already have this collection installed if you are using the ansible package. It is not included in ansible-core. To check whether it is installed, run ansible-galaxy collection list.

To install it, use: ansible-galaxy collection install graphiant.naas. You need further requirements to be able to use this module, see Requirements for details.

To use it in a playbook, specify: graphiant.naas.graphiant_device_lifecycle.

New in graphiant.naas 26.10.0

Synopsis

  • Changes device lifecycle state with PUT /v1/devices/bringup and schedules or rolls back software upgrades with PUT /v1/devices/upgrade/schedule. Matches the portal’s Maintain > Device Lifecycle page. Use graphiant.naas.graphiant_device_lifecycle_info to query current status instead.

  • operation=change_state sets lifecycle_state to activated, staging, maintenance, deactivated, or decommissioned. Idempotent against live GET /v1/edges-summary status — only devices that differ are pushed. decommissioned is only accepted when the device’s current state is deactivated (matches the portal UI); the module fails the task otherwise rather than sending a request the device isn’t in a valid state for.

  • operation=schedule_upgrade schedules a software update to a release channel (release: Stable/Recommended/Latest/Custom — matches the portal’s own “Change Release” dropdown exactly; Custom only resolves to anything for an enterprise that has a custom image enabled, and is otherwise rejected by the API) via upgrade_action (InstallActivate/Install/Activate, optional ts to run later); operation=rollback schedules action=Activate back to each device’s upgradeSummary.lastRunningVersion — the only target either operation supports; neither can be pinned to an arbitrary exact build string, matching what the portal UI itself allows. Both are actions rather than fully declarative state, so a device that does need the change always reports changed=true on success — except one idempotency-style skip each: schedule_upgrade skips a device already resolved to be running the requested release channel’s current build (skipped_devices); rollback skips a device with no lastRunningVersion — its *only* skip, since lastRunningVersion always differs from what’s currently running, so there’s no “already on this version” case; a repeat rollback right after a previous one simply targets whichever build the device just came from, reporting changed=true again. schedule_upgrade additionally does not schedule a device whose portal Connectivity Status is Down (ttConnCount below 1/Impaired) rather than attempting a push with nothing to deliver it over — unlike the other two skips, this one (not_connected_devices) fails the task, even when other devices in the same batch were scheduled successfully (msg is replaced with a summary; see notes). Both schedule_upgrade and rollback also skip (schedule_in_progress_devices) a device whose existing schedule hasn’t reached a terminal state yet, to avoid racing a still-in-flight prior schedule for the same device — a soft skip like skipped_devices, not a failure (see notes).

  • Supply config_file for a device_lifecycle list, and/or device with lifecycle_state / release to run a single device or override one device from the file.

  • Precedence is NOT the same for every option: operation, upgrade_action, and ts apply to the whole run and are module-parameter only (no config_file equivalent). lifecycle_state and release follow the usual rule — a module parameter set via device overrides that one device’s entry in the file. verify_for_insync and wait_for_completion work the OPPOSITE way: the module parameter only sets the whole-run default, and a device’s own value in config_file always wins over it for itself — see notes.

Requirements

The below requirements are needed on the host that executes this module.

  • python >= 3.7

  • graphiant-sdk >= 26.10.0

  • tabulate (optional; logs a pre-change device table with detailed_logs=true when installed)

Parameters

Parameter

Comments

access_token

string

Bearer token for API authentication (for example, from graphiant login, which opens a browser for sign-in (SSO or non-SSO) and retrieves the token).

If not passed as a module argument, the collection reads GRAPHIANT_ACCESS_TOKEN (set after graphiant login when you source ~/.graphiant/env.sh).

When a bearer token is present (module argument or environment), it takes precedence over username and password.

If no valid token is available, the module authenticates with username and password when both are supplied.

config_file

string

Path to YAML that can drive the whole task by itself (only host / username / password / access_token and operation still need to be set on the task) — optional only if device is set instead.

Relative paths resolve using the collection config path (see GRAPHIANT_CONFIGS_PATH).

Top-level key device_lifecycle is a list of single-key dicts keyed by portal device name. For operation=change_state, the value has lifecycle_state and optionally verify_for_insync (overrides the module option, per device). For operation=schedule_upgrade, the value has release and optionally wait_for_completion and/or verify_for_insync (each overrides its matching module option, per device). For operation=rollback, the value only needs wait_for_completion / verify_for_insync if overriding those (the rollback target is always the device’s own last running version — an empty dict is enough otherwise).

upgrade_action and ts apply to the whole batch (one PUT schedules every device’s upgrade under a single action/time) and so, like operation, are module-parameter only — they cannot be set in this file.

detailed_logs

boolean

Enable detailed logging in the task result message.

Choices:

  • false ← (default)

  • true

device

string

Portal device name. With config_file, optional override for this one device.

Required when config_file is omitted.

host

aliases: base_url

string / required

Graphiant portal host URL for API connectivity.

Example: “https://api.graphiant.com”

lifecycle_state

string

Target lifecycle state (operation=change_state with device).

Choices:

  • "activated"

  • "staging"

  • "maintenance"

  • "deactivated"

  • "decommissioned"

operation

string / required

The device lifecycle operation to perform. Module-parameter only (not settable in config_file) — one invocation runs exactly one operation for every device in the batch, so there is no per-device or per-file notion of it; pass it with -e operation=... or set it directly on the task (this collection’s device_lifecycle_management.yml playbook does this via its per-operation tags).

Choices:

  • "change_state"

  • "schedule_upgrade"

  • "rollback"

password

string

Graphiant portal password for authentication.

Required for password-based login when no valid bearer token is available from access_token or GRAPHIANT_ACCESS_TOKEN.

release

string

Target software release channel (operation=schedule_upgrade with device) — matches the portal’s own “Change Release” dropdown exactly. Custom only resolves to anything for an enterprise that has a custom image enabled; offered here unconditionally and otherwise rejected by the API. There is no way to target an arbitrary exact build string instead of a channel, matching what the portal UI itself allows.

Ignored for operation=rollback (the rollback target is always the device’s own upgradeSummary.lastRunningVersion — there is no override).

Choices:

  • "Stable"

  • "Recommended"

  • "Latest"

  • "Custom"

state

string

Only present is supported; use operation to select the action.

Choices:

  • "present" ← (default)

ts

dictionary

Optional schedule time for operation=schedule_upgrade / operation=rollback: {"seconds": <int>, "nanos": <int>}. Applies to every device in the batch (one PUT call, one time) — module-parameter only, not settable in config_file; omit to run now.

upgrade_action

string

How to apply the upgrade (operation=schedule_upgrade).

InstallActivate: download and install/activate immediately (portal “Download & Install”).

Install: download only, do not activate (portal “Download Only”).

Activate: activate a version already downloaded to the device (portal “Install Only”).

Applies to every device in the batch (one PUT call, one action) — module-parameter only, not settable in config_file; defaults to InstallActivate when not given.

Choices:

  • "InstallActivate"

  • "Install"

  • "Activate"

username

string

Graphiant portal username for authentication.

Required for password-based login when no valid bearer token is available from access_token or GRAPHIANT_ACCESS_TOKEN.

verify_for_insync

boolean

Poll for the device to reach portalStatus=Ready. For operation=change_state, after activated / staging / maintenance changes (no effect on deactivated / decommissioned). For operation=schedule_upgrade / operation=rollback, after that device’s schedule reaches Success — only consulted for a device that is also being watched by wait_for_completion (see notes); has no effect on a device whose schedule reached Failed or timed out, or one with wait_for_completion=false.

Sets the whole-run default; a device’s own verify_for_insync key in config_file overrides this default for that device only. Defaults to true when neither is given.

Choices:

  • false

  • true

wait_for_completion

boolean

For operation=schedule_upgrade / operation=rollback, poll each scheduled device’s upgradeSummary.schedule.state after the PUT until it reaches a terminal value (Success or Failed) or a timeout is reached (see notes); false also disables the verify_for_insync Ready poll that would otherwise follow a Success for that device, since without this poll there’s no Success to follow. Has no effect on operation=change_state.

Sets the whole-run default; a device’s own wait_for_completion key in config_file (alongside its release) overrides this default for that device only. Defaults to true when neither is given.

Choices:

  • false

  • true

Attributes

Attribute

Support

Description

check_mode

Support: partial

change_state reads current device state in check mode and sets changed from whether a push would be needed, without sending the PUT (same convention as graphiant.naas.graphiant_device_system); the readiness poll is skipped in check mode. schedule_upgrade and rollback skip the mutating PUT in check mode but, for a device that isn’t skipped (see skipped_devices), always report changed=true when resolved successfully — there’s no live state to compare a one-off scheduled action against the way operation=change_state can. In check mode, msg is prefixed with [check_mode] and says what would happen (e.g. “Would change device lifecycle state”) rather than “Successfully changed …”, so a check-mode run cannot be mistaken for one that actually applied changes just by reading the message.

Full support for change_state; partial for schedule_upgrade/rollback.

diff_mode

Support: partial

change_state shows before/after lifecycle_state; rollback shows before/after version. schedule_upgrade shows before/after version too, where after is the release channel’s current build resolved from the software releases catalog (see skipped_devices) when resolvable, otherwise just the requested release channel name.

Supports Ansible’s --diff for change_state, schedule_upgrade, and rollback.

Notes

Note

  • After operation=change_state succeeds for activated/staging/maintenance (skipped for deactivated/decommissioned), the module polls GET /v1/edges-summary until portalStatus=Ready and the device has at least 2 tunnel-terminator connections, or a timeout is reached (reuses the same verify_device_portal_status helper as graphiant.naas.graphiant_device_config). Devices that don’t reach Ready in time land in not_insync_devices and fail the task (msg is replaced with a summary naming them; the state change itself was still applied — see configured_devices); devices that did reach Ready land in insync_devices. Set verify_for_insync=false to skip this for every device, or set verify_for_insync per device in config_file. Devices sharing the same desired lifecycle_state are applied via a single batched PUT call (matching the portal UI’s own behavior), not one call per device; the readiness poll afterward still runs concurrently per device, not one at a time, and each retry logged while polling names the device by hostname (not just its numeric ID) so concurrent devices’ log lines can be told apart.

  • After operation=schedule_upgrade / operation=rollback succeeds, the module polls each scheduled device’s upgradeSummary.schedule.state until it reaches Success or Failed (every other value, including any new one the API might add, means still in progress — not a failure, since downloads/installs can take minutes), landing in completed_devices / failed_devices / in_progress_devices. A device whose schedule reaches Success is then also polled for portalStatus=Ready the same way operation=change_state is (same verify_for_insync toggle, same insync_devices/not_insync_devices result fields) — Success doesn’t mean the portal has settled back to Ready yet. A Failed schedule, or a non-empty not_insync_devices, fails the task even though the schedule/rollback was still applied. Set wait_for_completion=false to skip the schedule-state poll (and, since there’s then no Success to follow, the Ready poll too) for every device, or override either toggle per device in config_file.

  • With detailed_logs=true and tabulate installed, every operation logs the targeted devices’ current state as a table before any PUT (see graphiant.naas.graphiant_device_lifecycle_info‘s detailed_logs note for column details). operation=change_state (outside check mode) logs the same table again afterward, re-fetched to show each device’s resulting state. operation=schedule_upgrade and operation=rollback additionally log the release channel -> current build table (from the same software releases catalog used to resolve skipped_devices and the diff after value) right before the devices table, so the skip/schedule decision for every device is auditable from the log alone.

  • A device or config_file device_lifecycle entry naming a device not found in GET /v1/edges-summary fails the task before any PUT is sent; every such unresolved device is collected and named together in one failure, not just the first one encountered, so a config file with several bad names surfaces all of them in a single run.

  • operation=schedule_upgrade / operation=rollback skip (schedule_in_progress_devices) a device whose existing upgradeSummary.schedule.state hasn’t reached Success/Failed yet, including Idle — submitting a new schedule while a prior one is still in progress can race the upgrade backend’s own duplicate-request guard and has been observed to fail with FailureReason: "Internal error". Not a failure here; this is reported the same way as skipped_devices (counted in the “N device(s) skipped” summary) rather than failing the task, since the device’s prior schedule is itself still making progress toward the same goal.

See Also

See also

graphiant.naas.graphiant_device_system

Configure device hostname, region, and site.

graphiant.naas.graphiant_device_lifecycle_info

Query device lifecycle state and software upgrade status.

Examples

- name: Change lifecycle state for devices from a config file
  graphiant.naas.graphiant_device_lifecycle:
    operation: change_state
    config_file: "sample_device_lifecycle.yaml"
    host: "{{ graphiant_host }}"
    username: "{{ graphiant_username }}"
    password: "{{ graphiant_password }}"
    detailed_logs: true
  register: lifecycle_result

- name: Move a single device to staging
  graphiant.naas.graphiant_device_lifecycle:
    operation: change_state
    device: "edge-1-sdktest"
    lifecycle_state: staging
    host: "{{ graphiant_host }}"
    username: "{{ graphiant_username }}"
    password: "{{ graphiant_password }}"

- name: Deactivate then decommission a device
  graphiant.naas.graphiant_device_lifecycle:
    operation: change_state
    device: "edge-1-sdktest"
    lifecycle_state: deactivated
    host: "{{ graphiant_host }}"
    username: "{{ graphiant_username }}"
    password: "{{ graphiant_password }}"

- name: Now safe to decommission (device is Deactivated)
  graphiant.naas.graphiant_device_lifecycle:
    operation: change_state
    device: "edge-1-sdktest"
    lifecycle_state: decommissioned
    host: "{{ graphiant_host }}"
    username: "{{ graphiant_username }}"
    password: "{{ graphiant_password }}"

- name: Download and install the Latest release now
  graphiant.naas.graphiant_device_lifecycle:
    operation: schedule_upgrade
    device: "edge-1-sdktest"
    release: "Latest"
    upgrade_action: "InstallActivate"
    host: "{{ graphiant_host }}"
    username: "{{ graphiant_username }}"
    password: "{{ graphiant_password }}"

- name: Download the Stable release only, for later activation
  graphiant.naas.graphiant_device_lifecycle:
    operation: schedule_upgrade
    device: "edge-1-sdktest"
    release: "Stable"
    upgrade_action: "Install"
    host: "{{ graphiant_host }}"
    username: "{{ graphiant_username }}"
    password: "{{ graphiant_password }}"

- name: Schedule an upgrade for several devices, from a config file
  graphiant.naas.graphiant_device_lifecycle:
    operation: schedule_upgrade
    config_file: "sample_device_lifecycle.yaml"  # devices + release, from the file
    upgrade_action: "InstallActivate"  # applies to the whole batch; module param only
    host: "{{ graphiant_host }}"
    username: "{{ graphiant_username }}"
    password: "{{ graphiant_password }}"

- name: Roll back a device to its previous running version
  graphiant.naas.graphiant_device_lifecycle:
    operation: rollback
    device: "edge-1-sdktest"
    host: "{{ graphiant_host }}"
    username: "{{ graphiant_username }}"
    password: "{{ graphiant_password }}"

- name: Override verify_for_insync for just one device in the batch
  graphiant.naas.graphiant_device_lifecycle:
    operation: change_state
    config_file: "sample_device_lifecycle.yaml"  # one device's own entry sets verify_for_insync: false
    host: "{{ graphiant_host }}"
    username: "{{ graphiant_username }}"
    password: "{{ graphiant_password }}"

Return Values

Common return values are documented here, the following are the fields unique to this module:

Key

Description

changed

boolean

Whether the operation made (or, in check mode, would make) changes.

Returned: always

completed_devices

list / elements=string

For schedule_upgrade / rollback, device names (a subset of configured_devices) whose upgradeSummary.schedule.state reached Success.

Returned: when applicable

configured_devices

list / elements=string

Device names updated (change_state) or scheduled (schedule_upgrade/rollback).

Returned: when applicable

details

dictionary

Raw manager result payload.

Returned: always

diff

dictionary

Ansible --diff payload (before/after) for change_state and rollback.

Returned: when playbook uses --diff and at least one device would change

failed_devices

list / elements=string

For schedule_upgrade / rollback, device names whose upgradeSummary.schedule.state reached Failed (see the detailed logs for each device’s failureReason). Non-empty fails the task (the schedule/rollback itself was still applied; see configured_devices). Set wait_for_completion=false to skip the poll and this check entirely.

Returned: when applicable

in_progress_devices

list / elements=string

For schedule_upgrade / rollback, device names whose upgradeSummary.schedule.state did not reach Success or Failed within the poll timeout — still in progress, not a failure (downloads/installs can take minutes). Use graphiant.naas.graphiant_device_lifecycle_info in a follow-up task to keep watching these.

Returned: when applicable

insync_devices

list / elements=string

Device names that were polled for readiness and reached portalStatus=Ready — the complement of not_insync_devices among the devices actually polled. For change_state, a subset of configured_devices polled after a activated/staging/maintenance change with verify_for_insync enabled. For schedule_upgrade/rollback, a subset of completed_devices (schedule reached Success) also polled because verify_for_insync was enabled for that device. Neither configured_devices nor completed_devices alone distinguishes devices that reached Ready from ones that didn’t, or from devices never polled at all (deactivated/decommissioned changes, verify_for_insync=false, or — for schedule_upgrade/rollback — a schedule that reached Failed/timed out, or wait_for_completion=false).

Returned: when applicable

msg

string

Result message from the operation, including detailed logs when detailed_logs is enabled.

Returned: always

not_connected_devices

list / elements=string

schedule_upgrade only — device names not scheduled because the device’s portal Connectivity Status is Down (ttConnCount 0 or missing): less than Impaired (ttConnCount>=1), so there’s no tunnel-terminator connection to actually deliver the upgrade over. Not attempted rather than sent and left to fail at the API; the rest of the batch is still scheduled normally, but a non-empty list here fails the task (msg replaced with a summary naming them, worded as “No devices were scheduled” instead of “Upgrade scheduled, but …” when this is the only reason changed is false).

Returned: when applicable

not_insync_devices

list / elements=string

Device names that did not reach portalStatus=Ready within the readiness poll timeout. Non-empty fails the task — the underlying change was still applied (change_state‘s state change, or schedule_upgrade/rollback‘s already-Success schedule; see configured_devices/completed_devices). Set verify_for_insync=false to skip the poll and this check entirely.

Returned: when applicable

operation

string

The operation that was performed.

Returned: always

schedule_in_progress_devices

list / elements=string

schedule_upgrade / rollback only — device names not (re-)scheduled because their existing upgradeSummary.schedule.state hadn’t reached Success/Failed yet (including Idle): submitting a new schedule here could race the upgrade backend’s own duplicate-request guard. Not a failure — reported the same way as skipped_devices (counted in the “N device(s) skipped” summary), since the device’s prior schedule is itself still progressing toward the same goal.

Returned: when applicable

skipped_devices

list / elements=string

Device names skipped — for change_state, because they already matched lifecycle_state; for schedule_upgrade, because the device already resolved to be running the requested target (only when that target could actually be resolved to a build — see msg/notes); for rollback, because the device has no lastRunningVersion to roll back to.

Returned: when applicable

Authors

  • Graphiant Team (@graphiant)