RPS Tasking Guide
Last updated on August 26, 2021.
Document Status: Document Developer Quality Pending.
Rapid Provisioning System (RPS) Tasking is a feature of RPS that provides a controlled, predictable method to automate complex tasks in correct sequence. A working knowledge of the entities and architecture of RPS is recommended prior to reading this guide.
Introduction
This guide provides an overview of the RPS Tasking architecture, a list of supporting documentation, RPS task assignment creation, and examples in PowerShell code.
Overview
The center of RPS Tasking capabilities is a Task Assignment. A task assignment is the assignment of the smallest unit of work, a Task Item, to a single Target Item.
To perform a complex sequence of steps, RPS uses a Task Map, which describes: a set of steps, what order they should be performed in, and what target items those steps apply to. The Task Map is the blueprint of the process or orchestration. Some examples of Task Maps include: provisioning a new server stack, performing complex patching, or maintenance routines such as issuing new certificates.
The result of assigning a task map to a target item is a Task Map Assignment, which is a set of task assignments that together, complete the complex process. A major benefit of RPS is the flexibility of Task Maps, which allows Administrators to author simple, reusable PowerShell runbooks, and compose them together into a complex process across multiple devices.
Glossary
The following terms are used in the Tasking Guide:
Term | Description | Aliases (Deprecated*) |
---|---|---|
Direct Assignment | The assignment of a task item directly to a target, without the use of a Task Map. | |
Map Assignment | The assignment of a task map to a target and its descendants. The result is a set of Task Assignments that together make up a complex orchestration. | TaskMapAssignment, Orchestration |
Runbook | PowerShell script which runs a simple task. Usually run in TMS. | |
Step | Identify a single step within a Task Map. | Task Map Step, TaskMapStep, TaskMapDefinition* |
Step Dependency | A dependency between a step and its dependent (previous) step. | TaskMapStepDependency, TaskMapDefDependency* |
Step Filter | A filter to narrow what target items the step applies to. | TaskMapStepFilter, TaskMapDefFilter* |
Target Item | A device which is the target of a task item or task map. | TargetItem, Target |
Task Assignment | Assignment of a task item to a target. Corresponds to a single job in TMS. | TaskAssignment, Assignment |
Task Item | Identifies a task (runbook). | TaskItem, Task |
Task Management Service | Used by RPS to run RPS Task Assignments. | TMS |
Task Map | Identifies a set of steps, what order they should be performed in, and what target items those steps apply to. | TaskMap, Map |
Target Item User Actions
The states in which actions on a Target Item may be classified are detailed below.
State | Description | Criteria |
---|---|---|
Pending | An action on a Target Item that is Pending. | Task Assignment(s) assigned to the Target Item are Pending user action. |
Optional | An action on a Target Item that is Optional. | Task Assignment(s) assigned to the Target Item have a state of Not Ready and are flagged as Optional. |
Retry | An action on a Target Item that is Retryable. | Task(s) assigned to the Target Item have a state of Canceled or ErrorStop. |
Task Map Authoring
A Task Map is a reusable blueprint for a set of steps that need to be performed on one or more devices. The Rps-Api module and cmdlets allow a user to quickly create complex task maps.
Example: Create a Task Map
This example demonstrates the method for creating a Task Map using the Rps-Api module. The example is a Task Map which first configures a hypervisor, and then creates a new VM.
Step 1: Create Task Map
Provide the Name and Type.
$map = New-RpsTaskMap -Name "Provision-VMs" -Type "Provision"
Step 2: Create Task Items
Next, create a Task Item for the runbooks that do the work.
$task1 = New-RpsTaskItem -WorkflowName "Configure-HyperV"
$task2 = New-RpsTaskItem -WorkflowName "New-VirtualMachine"
Step 3: Create Steps
Next, create a step for each of the Task Items. You can specify the Task Item using the "RunbookName", "TaskItem", or "TaskItemId" parameter.
$step1 = New-RpsTaskMapStep -TaskMap $map -RunbookName "Configure-HyperV" -TargetItemType "Computer"
$step2 = New-RpsTaskMapStep -TaskMap $map -TaskItem $task1 -TargetItemType "Computer"
$step3 = New-RpsTaskMapStep -TaskMapId $map.Id -TaskItemId $task2.Id -TargetItemType "VirtualMachine"
Note
The TargetItemType parameter is required and is used to determine which type of Target Item to assign to. To use more advanced filtering, see Step 5: Create Filters, below.
Step 4: Create Dependencies
Create a dependency between $step1
and $step2
. RPS uses dependencies to evaluate when a task assignment is ready to be run.
In this example, $step2
depends on $step1
, so it will run only after $step1
has completed.
New-RpsTaskMapStepDependency -PreviousStep $step1 -Step $step2
Step 5: Create Filters
Use Step Filters to further restrict what Target Items a Step applies to. For our example, we may only want to provision Hyper-V VMs, so we'll make sure the Target VMs have a property called "HostType" with a value of "HyperV".
New-RpsTaskMapStepFilter -TaskMapStep $step2 -PropertyName "HostType" -PropertyValue "HyperV"
Example: Simplified Task Map
The example above can be simplified to allow easier Task Map creation. Here is an example of the same Task Map, simplified.
$map = New-RpsTaskMap -Name "Provision-VMs" -Type "Provision"
$step1 = New-RpsTaskMapStep -TaskMap $map -RunbookName "Configure-HyperV" -TargetItemType "Computer"
$step2 = New-RpsTaskMapStep -TaskMap $map -RunbookName "New-VirtualMachine" -TargetItemType "VirtualMachine" `
-Dependencies @($step1) -Filters @{ HostType = "HyperV" }
Note
The example assumes that the Task Items were created. Typically, Runbooks will be authored and imported into RPS as Task Items before Task Maps are created.
Target Matching
When a Task Map is assigned to a Target Item, each Step is compared to the Target and its descendant items. By default, RPS doesn't enforce that a step matches a target. By default, RPS also allows a Step to match multiple Target Items, though sometimes the desired behavior is to match a single item only.
To designate a Step as required, use the optional parameter, IsTargetRequired
.
To designate a Step to allow or prevent multiple matching targets, use the optional parameter, AllowMultipleTargets
.
Warning
A Task Map will fail if it is assigned to the same Target Item multiple times while AllowMultipleTargets = false
,
because this configuration does not allow multiple targets.
Example: Required Target Item, No Multiples
In our sample Task Map, we probably want the Configure-HyperV
step to apply to a single Computer hosting Hyper-V.
We will change the first Step to require a Target and disallow multiple matches.
We won't change the second step, meaning that this Task Map will work for a Computer with zero or more VMs.
$map = New-RpsTaskMap -Name "Provision-VMs" -Type "Provision"
$step1 = New-RpsTaskMapStep -TaskMap $map -RunbookName "Configure-HyperV" -TargetItemType "Computer" -IsTargetRequired $true -AllowMultipleTargets $false
$step2 = New-RpsTaskMapStep -TaskMap $map -RunbookName "New-VirtualMachine" -TargetItemType "VirtualMachine" -Dependencies $step1 -Filters @{ HostType = "HyperV" }
Task Map Assignment
After creating a Task Map, assign it to a Target Item to create a Task Map Assignment. The map assignment will contain one or more Task Assignments that apply to the Target Item and its descendants.
Note
In v2.2 and earlier, RPS only allowed Task Maps to be assigned to root Target Items (Containers).
As of v2.3, RPS allows a Task Map to be assigned to any Target Item, allowing more flexibility in how Target Items are structured, and more re-use of Task Maps and Runbooks. This has the side effect that $taskMap.GetContainers() may no longer retrieve the actual targets of the Task Map.
Assign Task Map to Target Item
The example below will create a Task Map, a Target Computer with 2 VMs, and assign the Map to the Target.
# Create Task Map
$map = New-RpsTaskMap -Name "Provision-VMs" -Type "Provision"
$step1 = New-RpsTaskMapStep -TaskMap $map -RunbookName "Configure-HyperV" -TargetItemType "Computer" -IsTargetRequired $true -AllowMultipleTargets $false
$step2 = New-RpsTaskMapStep -TaskMap $map -RunbookName "New-VirtualMachine" -TargetItemType "VirtualMachine" -Dependencies $step1 -Filters @{ HostType = "HyperV" }
# Create Computer & 2 VMs
$server = New-RpsTargetItem -Type Computer -Name "Server-01"
$vm1 = New-RpsTargetItem -ParentItem $server -Type VirtualMachine -Name "VM-01" -Properties @{ HostType = "HyperV" }
$vm2 = New-RpsTargetItem -ParentItem $server -Type VirtualMachine -Name "VM-02" -Properties @{ HostType = "HyperV" }
# Assign Task Map to Computer
New-RpsTaskAssignment -TaskMap $map -TargetItem $server
The result of this assignment is a Map Assignment consisting of 3 Task Assignments.
Step | Task | Target | Dependencies |
---|---|---|---|
1-1 | Configure-HyperV | Server-01 | |
2-1 | New-VirtualMachine | VM-01 | Step 1-1 |
2-2 | New-VirtualMachine | VM-02 | Step 1-1 |
Assign Task Map to Target Group
A Task Map can also be assigned to a Target Group. The Target Group is used simply as a collection of related Target Items. The assignment will result in a new Map Assignment to each Target in the Group, and each Target will be validated separately.
The example below will create a Task Map, a Target Group with 2 Servers, and assign the Map to the Group.
# create a server with 2 VMs
$vmProps = @{ Type = "VirtualMachine"; Properties = @{ HostType = "HyperV" } }
$server = New-RpsTargetItem -Type Computer -Name "Server01"
$vm1 = New-RpsTargetItem -ParentItem $server -Name "VM-01" @vmProps
$vm2 = New-RpsTargetItem -ParentItem $server -Name "VM-02" @vmProps
# create a server with 1 VM
$server2 = New-RpsTargetItem -Type Computer -Name "Server02"
$vm3 = New-RpsTargetItem -ParentItem $server2 -Name "VM-03" @vmProps
# create a group with both servers
$group = New-RpsTargetGroup -Name "Servers" -Type "Server"
$group.AddChildren($server, $server2)
Update-RpsTargetGroup -TargetGroup $group
# assign the map to the group
New-RpsTaskAssignment -TaskMap $map -TargetGroup $group
Assign a Task Map to run on the Local Node
By default, Task Assignments will be executed on the Target's Node. Optionally, a Task Map can also be assigned to a Target but executed on the Local (current) Node, instead of the Target's Node. This may be useful when building a child Node from a parent Node. The work to provision the child Node's Virtual Machines will happen locally (on the parent node), but the target computers are assigned to the child node.
Assign a Task Map to a Target and run on the Local Node by using the -RunOnLocalNode
switch with the New-RpsTaskAssignment
cmdlet.
Example: Assign a Task Map to Child Target, but run on Parent Node
# Create Task Map
$map = New-RpsTaskMap -Name "Provision-VMs" -Type "Provision"
$step1 = New-RpsTaskMapStep -TaskMap $map -RunbookName "Configure-HyperV" -TargetItemType "Computer" -IsTargetRequired $true -AllowMultipleTargets $false
$step2 = New-RpsTaskMapStep -TaskMap $map -RunbookName "New-VirtualMachine" -TargetItemType "VirtualMachine" -Dependencies $step1 -Filters @{ HostType = "HyperV" }
# Create Computer & 2 VMs
$server = New-RpsTargetItem -Type Computer -Name "Server-01" -Node $childNode
$vm1 = New-RpsTargetItem -ParentItem $server -Type VirtualMachine -Name "VM-01" -Properties @{ HostType = "HyperV" }
$vm2 = New-RpsTargetItem -ParentItem $server -Type VirtualMachine -Name "VM-02" -Properties @{ HostType = "HyperV" }
# Assign Task Map to Computer, but run on current Node
New-RpsTaskAssignment -TaskMap $map -TargetItem $server -RunOnLocalNode
Scheduled Task Assignments
RPS v2.3 supports the ability to schedule task assignments. These task assignments will not be executed until the scheduled date.
To schedule a Task Map Assignment, use the optional parameter, StartDate
.
Example: Scheduled Task Map Assignment
New-RpsTaskAssignment -TaskMap $map -TargetItem $server -StartDate "8/27/18 16:00"
Assignment Validation
When assigning a Task Map to a Target Item, there may be some steps that don't meet the Task Map's requirements. For example, if a Step requires a matching Target but none is found, the assignment will fail, and an error returned to the user.
Invalid Targets
This code:
# Assign Task Map to VM1
New-RpsTaskAssignment -TaskMap $map -TargetItem $vm1
Will result in this message:
WARNING: Error assigning Task Map: Provision-VMs to Container: VirtualMachine-VM-01
Step requires a matching target item.
Duplicate Assignments
RPS does not allow the same Task Map to be assigned to the same Target Item multiple times.
This code:
# Assign Task Map to Server01 Twice
New-RpsTaskAssignment -TaskMap $map -TargetItem $server
New-RpsTaskAssignment -TaskMap $map -TargetItem $server
Will result in this message:
WARNING: Error assigning Task Map: Provision-VMs to Container: Computer-Server01
Container is already assigned to the Task Map.
Note
The restriction of duplicate assignments is largely in place for backwards-compatibility reasons and will likely be removed from RPS in the future. Conceptually, a Task Map represents a process that may run multiple times on the same target devices. For now, the two alternatives are to clone a task map in order to run it again or reset the task map assignment so it will run again.
Dependency Scope
If we change the "Provision-VMs" Task Map to include a third step which makes sure the VM is started and waits for the OS to boot, it will have a dependency on Step 2.
$map = New-RpsTaskMap -Name "Provision-VMs" -Type "Provision"
$step1 = New-RpsTaskMapStep -TaskMap $map -RunbookName "Configure-HyperV" -TargetItemType "Computer" `
-IsTargetRequired $true -AllowMultipleTargets $false
$step2 = New-RpsTaskMapStep -TaskMap $map -RunbookName "New-VirtualMachine" -TargetItemType "VirtualMachine" -Dependencies $step1
$step3 = New-RpsTaskMapStep -TaskMap $map -RunbookName "Start-VirtualMachine" -TargetItemType "VirtualMachine" -Dependencies $step2
If we assign that map to our server and 2 VMs, the following Task Assignments will be created:
Step | Task | Target | Dependencies |
---|---|---|---|
1-1 | Configure-HyperV | Server-01 | |
2-1 | New-VirtualMachine | VM-01 | Step 1-1 |
2-2 | New-VirtualMachine | VM-02 | Step 1-1 |
3-1 | Start-VirtualMachine | VM-01 | Steps 2-1, 2-2 |
3-2 | Start-VirtualMachine | VM-02 | Steps 2-1, 2-2 |
Looking at the dependencies, you can see that the VM-01 won't start (Step 3-1) until VM-02 has been created (Step 2-2). Likewise, VM-02 waits on VM-01. If we add more Steps that apply to VMs and more VMs to our Server, we'd be creating many dependencies that aren't necessary.
Example 1: Use Scope to narrow Dependencies
Instead of creating dependencies to every target that matched a previous step, we can specify a narrower Scope when we define a Dependency.
In RPS v2.3, we've included a new Scope
parameter when creating Dependencies.
$map = New-RpsTaskMap -Name "Provision-VMs" -Type "Provision"
$step1 = New-RpsTaskMapStep -TaskMap $map -RunbookName "Configure-HyperV" -TargetItemType "Computer" -IsTargetRequired $true -AllowMultipleTargets $false
$step2 = New-RpsTaskMapStep -TaskMap $map -RunbookName "New-VirtualMachine" -TargetItemType "VirtualMachine" -Dependencies $step1
$step3 = New-RpsTaskMapStep -TaskMap $map -RunbookName "Start-VirtualMachine" -TargetItemType "VirtualMachine"
New-RpsTaskMapStepDependency -Step $step3 -PreviousStep $step2 -Scope Self
Example 2: Use Scope in-line
Note
Scope can be added to a TaskMapStep
as a TaskMapStep
parameter.
The scope will act on the dependency parameters supplied. The scope will default to target if not specified.
New-RpsTaskItem -WorkflowName "Configure-HyperV"
New-RpsTaskItem -WorkflowName "New-VirtualMachine"
New-RpsTaskItem -WorkflowName "Start-VirtualMachine"
$map = New-RpsTaskMap -Name "Provision-VMs" -Type "Provision"
$step1 = New-RpsTaskMapStep -TaskMap $map -RunbookName "Configure-HyperV" -TargetItemType "Computer" -IsTargetRequired $true -AllowMultipleTargets $false
$step2 = New-RpsTaskMapStep -TaskMap $map -RunbookName "New-VirtualMachine" -TargetItemType "VirtualMachine" -Dependencies $step1 -Scope Self
$step3 = New-RpsTaskMapStep -TaskMap $map -RunbookName "Start-VirtualMachine" -TargetItemType "VirtualMachine"
If we assign that map to our server and 2 VMs, the following Task Assignments will be created:
Step | Task | Target | Dependencies |
---|---|---|---|
1-1 | Configure-HyperV | Server-01 | |
2-1 | New-VirtualMachine | VM-01 | Step 1-1 |
2-2 | New-VirtualMachine | VM-02 | Step 1-1 |
3-1 | Start-VirtualMachine | VM-01 | Step 2-1 |
3-2 | Start-VirtualMachine | VM-02 | Step 2-2 |
Table: Dependency Scopes
The following Scopes are supported:
Scope | Description |
---|---|
Target | Indicates that dependencies will be to the Target of the Task Map, which is the assigned Target Item and all its descendants. This is the default value and the behavior of RPS prior to v2.3. |
Parent | Indicates that dependencies will be to the Parent Target Item of the previous step and any descendants. |
Self | Indicates that dependencies will be to the Target Item of the previous step and any descendants. |
Assignment Code Examples
Assign Task Item to Target Item for Execution
Both the Task Item and the Target Item objects must exist prior to assigning a Task Item to a Target Item.
The following example shows the method of assignment.
You can add a StartDate
to the task assignment so Master-Controller won't start execution until the DateTime has been met.
$taskAssignments = New-RpsTaskAssignment -TaskItem $AlwaysCompletes -TargetItem $targetItem -StartDate (Get-Date).AddMinutes(15)
Assign Task Map to Target Item for Execution
Both the Task Map and the Target Item objects must exist prior to assigning a Task Map to a Target Item. The following example shows the method of assignment.
$taskAssignments = New-RpsTaskAssignment -TaskMap $TaskAssignmentTaskMap -TargetItem $targetItem
Assign Task Item to Target Group for Execution
Both the Task Item and the Target Group objects must exist prior to assigning a Task Item to a Target Group. The following example shows the method of assignment.
$taskAssignments = New-RpsTaskAssignment -TaskItem $AlwaysCompletes -TargetGroup $targetGroup
Assign Task Map to Target Group for Execution
Both the Task Map and the Target Group objects must exist prior to assigning a Task Map to a Target Group. The following example shows the method of assignment.
$taskAssignments = New-RpsTaskAssignment -TaskMap $TaskAssignmentTaskMap -TargetGroup $targetGroup