New to Kestra?
Use blueprints to kickstart your first workflows.
Fire on new phpIPAM address assignments, alert Slack or auto-flag missing hostnames, and log the result for network engineering teams.
An IP address handed out without a hostname is the start of a long-term mystery: six months later nobody can tell what is actually using it, whether it is safe to reclaim, or who to ask. phpIPAM records every new address as it is assigned, but it has no policy that catches a blank hostname the moment it happens, only a static record waiting for someone to notice. This blueprint watches a subnet in real time, checks every new address against a hostname-required policy, and can flag the gap for review automatically once you have explicitly said this flow is allowed to.
This blueprint was created by Mohit Jeswani.
watch_subnet (io.kestra.plugin.phpipam.ipam.address.NewAddressTrigger) polls a
subnet and fires one execution per newly detected address, deduplicated via the
namespace KV store so each address fires exactly once.get_address (io.kestra.plugin.phpipam.ipam.address.Get) re-fetches the full address
record by trigger.addressId, reading the authoritative current hostname rather than
trusting the trigger's own summary. Read-only; nothing is changed here.evaluate (io.kestra.plugin.core.output.OutputValues) classifies the address as
COMPLIANT, NONCOMPLIANT_AUTO_FLAG, NONCOMPLIANT_NEEDS_HUMAN, or PROBE_FAILED,
folding confirm_flag_noncompliant into the non-compliant classification itself.route (io.kestra.plugin.core.flow.Switch):io.kestra.plugin.phpipam.ipam.address.Update (the
safe remediation, since writing a review note into the description changes no network
configuration), then posts a Slack notice.summary logs the severity, closing the governance cycle.errors alerts Slack if the flow itself fails, for example an expired app token.confirm_flag_noncompliant to allow
it.address.NewAddressTrigger used as a standing event-driven compliance gate, distinct from
this repo's existing phpIPAM blueprints, which scan a subnet on a schedule for capacity,
stale reservations, or VLAN/VRF drift rather than reacting to a single new assignment in
real time.phpIPAM records a new address as it happens, but it has no hostname policy, no escalation,
and no Slack integration of its own. Kestra keeps confirm_flag_noncompliant as an explicit
flow input, turns a trigger detection into a policy decision, and keeps a full execution
history of every address this flow has seen and what it did about it.
A local phpIPAM instance can be run via the official phpipam/phpipam-www and
phpipam/phpipam-cron Docker images (with a MariaDB/MySQL container) for a fully local
end-to-end test, no managed account required.
PHPIPAM_APP_TOKEN: the phpIPAM API app token used by get_address and flag_address,
and by the watch_subnet trigger. In Kestra OSS, provide it as the base64-encoded
environment variable SECRET_PHPIPAM_APP_TOKEN.SLACK_WEBHOOK_URL: used by all three Slack alert cases and the errors block. In Kestra
OSS, provide it as the base64-encoded environment variable SECRET_SLACK_WEBHOOK_URL.| Input | Default | Purpose |
|---|---|---|
base_url |
http://localhost |
phpIPAM instance root URL |
app_id |
myapp |
phpIPAM API application identifier |
confirm_flag_noncompliant |
false |
Authorizes this flow to flag a missing hostname itself |
The watched subnet is set directly on the watch_subnet trigger's subnetId, not as a flow
input; see Pitfalls.
{{ trigger.addressId }} / .ip / .hostname / .subnetId: the newly detected address,
as NewAddressTrigger reports it.{{ outputs.get_address.address }}: the full, re-fetched address record (hostname,
description, owner, tag, mac, and more).{{ outputs.evaluate.values.severity }}: COMPLIANT, NONCOMPLIANT_AUTO_FLAG,
NONCOMPLIANT_NEEDS_HUMAN, or PROBE_FAILED.NewAddressTrigger's own Javadoc example uses io.kestra.core.tasks.log.Log for its
companion Log task, which is not a real Kestra class; the correct, verified class is
io.kestra.plugin.core.log.Log, used throughout this blueprint instead. Flagging this as a
stale example in the plugin's own source, not something this blueprint itself does.address.Update's field for the address description is named resourceDescription, not
description, even though it updates phpIPAM's description field; verified directly
against the task's source, since its own Javadoc example does not show this field at all.subnetId, baseUrl, appId, and auth are trigger-level configuration, not flow
inputs; a polling trigger has no per-execution input overrides the way a Schedule
trigger does, so watching a different subnet means editing the trigger block directly.NewAddressTrigger emits one execution per newly detected address, one at a time per poll
cycle (the remaining new addresses in the same poll fire on the next cycle); a burst of
address assignments produces a burst of flow executions and possible Slack alerts, not one
aggregated message.PHPIPAM_APP_TOKEN and SLACK_WEBHOOK_URL secrets.watch_subnet's subnetId to
its real ID.log_compliant fires.confirm_flag_noncompliant: false; confirm
alert_noncompliant fires.confirm_flag_noncompliant: true, assign a third address with no hostname, and
confirm flag_address writes the review note and alert_auto_flagged fires.evaluate to also require a non-blank owner or description, not just a
hostname, for a stricter asset-tracking policy.io.kestra.plugin.phpipam.ipam.subnet.Get to
route the Slack alert to the team that owns that VLAN instead of one shared channel.watch_subnet trigger
configuration, one per subnet your team is responsible for.