Octopus.Script exported 2018-01-31 by tclydesdale belongs to ‘AWS’ category.
This step will Update, Create or Delete a Resource Record from an Route 53 hosted Domain Name.
Works well with the “AWS - Launch EC2 Instance” Community Step Template.
AWS Tools for Windows PowerShell must be installed on the Server/Target you plan on running this step template on.
Parameters
When steps based on the template are included in a project’s deployment process, the parameters below can be set.
Hosted Zone ID
odZoneId = Zxxxxxxxxxxxxx
The Hosted Zone ID of the Domain Name you would like to work with.
Action
odAction = UPSERT
The Action you would like to perform - Update, Create or Delete a Resource Record from an Route 53 hosted Domain Name.
Name
odName =
The Name is the full Domain Name Address you would like to work with. For example:
- database01.example.com
Resource Address
odResourceAddress =
The Address (IP or Domain Name) of the Resource you would like the Resource Record to point to. For example:
- 8.8.8.8 (e.g. A Record)
- webserver01.example.com (e.g. CNAME Record)
Record Type
odType = A
The Type of Resource Record you would like to work with. For example:
- A (e.g. 8.8.8.8)
- CNAME (e.g. webserver01.example.com)
Further Reading: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html
TTL (Time to Live)
odTtl = 600
The amount of time (in seconds) a Resource Record should be cached for.
Further Reading: https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-values-basic.html#rrsets-values-basic-ttl
Wait for Sync
odWait = True
If the Step should wait for the Resource Record to sync to all Name Servers before proceeding to the next Step.
Comment (Optional)
odComment =
The Comment provided in this field is for auditing purposes, and is not visible in the AWS Route 53 Web Interface (it’s only accessible via the API).
Access Key (Kind-of Optional)
odAccessKey =
An Access Key with permissions to create the desired EC2 instance. Note: If empty, this step will attempt to use the value contained in the Machine Environment Variable “AWS_ACCESS_KEY”.
Further Reading: https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html
Secret Key (Kind-of Optional)
odSecretKey =
The Secret Key associated with the above Access Key. Note: If empty, this step will attempt to use the value contained in the Machine Environment Variable “AWS_SECRET_KEY”.
Further Reading: https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html
Script body
Steps based on this template will execute the following PowerShell script.
# Running outside octopus
param(
[string]$odZoneId,
[string]$odAction,
[string]$odName,
[string]$odResourceAddress,
[string]$odType,
[string]$odTtl,
[string]$odWait,
[string]$odComment,
[string]$odAccessKey,
[string]$odSecretKey,
[switch]$whatIf
)
$ErrorActionPreference = "Stop"
function Get-Param($Name, [switch]$Required, $Default) {
$result = $null
if ($OctopusParameters -ne $null) {
$result = $OctopusParameters[$Name]
}
if ($result -eq $null) {
$variable = Get-Variable $Name -EA SilentlyContinue
if ($variable -ne $null) {
$result = $variable.Value
}
}
if (!$result -or $result -eq $null) {
if ($Default) {
$result = $Default
} elseif ($Required) {
throw "Missing parameter value $Name"
}
}
return $result
}
# More custom functions would go here
& {
param(
[string]$odZoneId,
[string]$odAction,
[string]$odName,
[string]$odResourceAddress,
[string]$odType,
[string]$odTtl,
[string]$odWait,
[string]$odComment,
[string]$odAccessKey,
[string]$odSecretKey
)
# If AWS key's are not provided as params, attempt to retrieve them from Environment Variables
if ($odAccessKey -or $odSecretKey) {
Set-AWSCredentials -AccessKey $odAccessKey -SecretKey $odSecretKey -StoreAs default
} elseif (([Environment]::GetEnvironmentVariable("AWS_ACCESS_KEY", "Machine")) -or ([Environment]::GetEnvironmentVariable("AWS_SECRET_KEY", "Machine"))) {
Set-AWSCredentials -AccessKey ([Environment]::GetEnvironmentVariable("AWS_ACCESS_KEY", "Machine")) -SecretKey ([Environment]::GetEnvironmentVariable("AWS_SECRET_KEY", "Machine")) -StoreAs default
} else {
throw "AWS API credentials were not available/provided."
}
If($odAction -ne "CREATE" -and $odAction -ne "DELETE" -and $odAction -ne "UPSERT") { throw "Invalid Action provided. Please use CREATE, DELETE or UPSERT." }
if ($odName -notmatch '.+?\.$') { $odName += '.' }
$change = (New-Object Amazon.Route53.Model.Change)
$change.Action = $odAction
$change.ResourceRecordSet = (New-Object Amazon.Route53.Model.ResourceRecordSet)
$change.ResourceRecordSet.Name = $odName
$change.ResourceRecordSet.Type = $odType
$change.ResourceRecordSet.TTL = $odTtl
if ($odResourceAddress -like '*,*') {
$($odResourceAddress -split ',') | Foreach-Object {
$change.ResourceRecordSet.ResourceRecords.Add(@{Value=$($_)})
}
} else {
$change.ResourceRecordSet.ResourceRecords.Add(@{Value=$odResourceAddress})
}
Write-Output ("------------------------------")
Write-Output ("Checking if Resource Record Set Exists:")
Write-Output ("------------------------------")
$resourceRecordSetObj = $(Get-R53ResourceRecordSet -HostedZoneId $odZoneId).ResourceRecordSets | Where {$_.Name -eq $odName}
$resourceRecordSetCount = ($resourceRecordSetObj | measure).Count
if ($odAction -eq "DELETE") {
if ($resourceRecordSetCount -gt 0) {
Write-Output ("The record '$($odName)' exists, deleting...")
} else {
Write-Output ("Cannot Delete: The record '$($odName)' does not exist, skipping...")
Exit
}
} elseif ($odAction -eq "CREATE") {
if ($resourceRecordSetCount -gt 0) {
Write-Output ("Cannot Create: The record '$($odName)' already exists, skipping...")
Exit
} else {
Write-Output ("The record '$($odName)' does not exist, creating record...")
}
} elseif ($odAction -eq "UPSERT") {
if ($resourceRecordSetCount -gt 0) {
Write-Output ("The record '$($odName)' already exists, updating record...")
} else {
Write-Output ("The record '$($odName)' does not exist, creating record...")
}
} else { throw "OMG - Unexpected result" }
$params = @{
HostedZoneId=$odZoneId
ChangeBatch_Comment=$odComment
ChangeBatch_Change=$change
}
Write-Output ("------------------------------")
Write-Output ("Listing DNS change/s to be made:")
Write-Output ("------------------------------")
$($params.ChangeBatch_Change) | Foreach-Object {
$resourceRecords=" | "
$($_.ResourceRecordSet.ResourceRecords) | Foreach-Object {
$resourceRecords += $_.Value + ","
}
Write-Output ($($_.Action.Value) + " | " + $($_.ResourceRecordSet.Name) + " | " + $($_.ResourceRecordSet.Type) + $($resourceRecords -replace ".$"))
}
$timeout = new-timespan -Seconds 30
$sw = [diagnostics.stopwatch]::StartNew()
$attempt = 1
while ($true) {
try {
$result = Edit-R53ResourceRecordSet @params
break
}
catch [Amazon.Route53.AmazonRoute53Exception] {
Write-Output ("$($_.Exception.errorcode)-$($_.Exception.Message)")
if ($attempt -eq 3) {
throw $_.Exception.errorcode + '-' + $_.Exception.Message
}
if ($sw.elapsed -gt $timeout) {throw "Timed out waiting for 'Edit-R53ResourceRecordSet' to succeed"}
Write-Output ("Attempt no.$($attempt) failed - Trying again in 5 seconds...")
Sleep -Seconds 5
$attempt++
}
}
Write-Output ("------------------------------")
Write-Output ("Checking the R53 Change status:")
Write-Output ("------------------------------")
$timeout = new-timespan -Seconds 120
$sw = [diagnostics.stopwatch]::StartNew()
while ($true) {
$currentState = (Get-R53Change -Id $result.Id).Status
if ($currentState -eq "INSYNC") {break}
if ([bool]($odWait -eq $false)) {break}
Write-Output ("$(Get-Date) | Waiting for R53 Change '$($result.Id)' to transition from state: $currentState")
if ($sw.elapsed -gt $timeout) {throw "Timed out waiting for desired state"}
Sleep -Seconds 5
}
Write-Output ("$(Get-Date) | R53 Change state: $currentState")
} `
(Get-Param 'odZoneId' -Required) `
(Get-Param 'odAction' -Required) `
(Get-Param 'odName' -Required) `
(Get-Param 'odResourceAddress' -Required) `
(Get-Param 'odType' -Required) `
(Get-Param 'odTtl' -Required) `
(Get-Param 'odWait' -Required) `
(Get-Param 'odComment') `
(Get-Param 'odAccessKey') `
(Get-Param 'odSecretKey')
Provided under the Apache License version 2.0.
To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.
{
"Id": "9271327d-6e8a-49d1-881a-3925c75aef56",
"Name": "AWS - Create a Route 53 Resource Record",
"Description": "This step will Update, Create or Delete a Resource Record from an Route 53 hosted Domain Name.\n\nWorks well with the \"_AWS - Launch EC2 Instance_\" Community Step Template.\n\n[AWS Tools for Windows PowerShell](http://aws.amazon.com/powershell/) must be installed on the Server/Target you plan on running this step template on.",
"Version": 1,
"ExportedAt": "2018-01-31T13:17:01.348Z",
"ActionType": "Octopus.Script",
"Author": "tclydesdale",
"Parameters": [
{
"Id": "6ec4f68e-02b7-4015-88aa-34a2a7dd8568",
"Name": "odZoneId",
"Label": "Hosted Zone ID",
"HelpText": "The Hosted Zone ID of the Domain Name you would like to work with.",
"DefaultValue": "Zxxxxxxxxxxxxx",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
},
"Links": {}
},
{
"Id": "2e0fa53b-d85a-4afd-9fb8-a44ddd28b598",
"Name": "odAction",
"Label": "Action",
"HelpText": "The Action you would like to perform - Update, Create or Delete a Resource Record from an Route 53 hosted Domain Name.",
"DefaultValue": "UPSERT",
"DisplaySettings": {
"Octopus.ControlType": "Select",
"Octopus.SelectOptions": "UPSERT|Update a Resource Record if exists, or Create a new one\nCREATE|Create a Resource Record\nDELETE|Delete a Resource Record"
},
"Links": {}
},
{
"Id": "843ef155-8583-417f-90dd-6e880ca175e2",
"Name": "odName",
"Label": "Name",
"HelpText": "The Name is the full Domain Name Address you would like to work with.\nFor example:\n- database01.example.com",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
},
"Links": {}
},
{
"Id": "956cb942-2d09-4bb4-b0a0-4c855d4f9b29",
"Name": "odResourceAddress",
"Label": "Resource Address",
"HelpText": "The Address (IP or Domain Name) of the Resource you would like the Resource Record to point to. For example:\n- 8.8.8.8 _(e.g. A Record)_\n- webserver01.example.com _(e.g. CNAME Record)_",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
},
"Links": {}
},
{
"Id": "d2734830-3915-4759-9b06-5a174540c337",
"Name": "odType",
"Label": "Record Type",
"HelpText": "The Type of Resource Record you would like to work with. For example:\n- A _(e.g. 8.8.8.8)_\n- CNAME _(e.g. webserver01.example.com)_\n\nFurther Reading:\n[https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/ResourceRecordTypes.html)",
"DefaultValue": "A",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
},
"Links": {}
},
{
"Id": "a62ded34-e6f4-4736-bea6-3c7294a5e6dd",
"Name": "odTtl",
"Label": "TTL (Time to Live)",
"HelpText": "The amount of time (in seconds) a Resource Record should be cached for.\n\nFurther Reading:\n[https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-values-basic.html#rrsets-values-basic-ttl](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-values-basic.html#rrsets-values-basic-ttl)",
"DefaultValue": "600",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
},
"Links": {}
},
{
"Id": "d14fbeaf-907b-4f5f-9efc-04a5ae2031f8",
"Name": "odWait",
"Label": "Wait for Sync",
"HelpText": "If the Step should wait for the Resource Record to sync to all Name Servers before proceeding to the next Step.",
"DefaultValue": "True",
"DisplaySettings": {
"Octopus.ControlType": "Checkbox"
},
"Links": {}
},
{
"Id": "d009432c-d746-42d1-b214-42ba78760d5b",
"Name": "odComment",
"Label": "Comment (Optional)",
"HelpText": "The Comment provided in this field is for auditing purposes, and is not visible in the AWS Route 53 Web Interface (it's only accessible via the API).",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
},
"Links": {}
},
{
"Id": "078ab1ac-4560-4241-8127-29bb293622b5",
"Name": "odAccessKey",
"Label": "Access Key (Kind-of Optional)",
"HelpText": "An Access Key with permissions to create the desired EC2 instance.\nNote: If empty, this step will attempt to use the value contained in the Machine Environment Variable \"AWS\\_ACCESS\\_KEY\".\n\nFurther Reading:\n[https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html](https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html)",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
},
"Links": {}
},
{
"Id": "0e06989b-4f09-4652-8c92-398d078c3cb5",
"Name": "odSecretKey",
"Label": "Secret Key (Kind-of Optional)",
"HelpText": "The Secret Key associated with the above Access Key.\nNote: If empty, this step will attempt to use the value contained in the Machine Environment Variable \"AWS\\_SECRET\\_KEY\".\n\nFurther Reading:\n[https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html](https://docs.aws.amazon.com/general/latest/gr/managing-aws-access-keys.html)",
"DefaultValue": "",
"DisplaySettings": {
"Octopus.ControlType": "SingleLineText"
},
"Links": {}
}
],
"Properties": {
"Octopus.Action.Script.Syntax": "PowerShell",
"Octopus.Action.Script.ScriptSource": "Inline",
"Octopus.Action.RunOnServer": "false",
"Octopus.Action.Script.ScriptBody": "# Running outside octopus\nparam(\n [string]$odZoneId,\n [string]$odAction,\n [string]$odName,\n [string]$odResourceAddress,\n [string]$odType,\n [string]$odTtl,\n [string]$odWait,\n [string]$odComment,\n [string]$odAccessKey,\n [string]$odSecretKey,\n [switch]$whatIf\n) \n\n$ErrorActionPreference = \"Stop\" \n\nfunction Get-Param($Name, [switch]$Required, $Default) {\n $result = $null\n\n if ($OctopusParameters -ne $null) {\n $result = $OctopusParameters[$Name]\n }\n\n if ($result -eq $null) {\n $variable = Get-Variable $Name -EA SilentlyContinue \n if ($variable -ne $null) {\n $result = $variable.Value\n }\n }\n\n if (!$result -or $result -eq $null) {\n if ($Default) {\n $result = $Default\n } elseif ($Required) {\n throw \"Missing parameter value $Name\"\n }\n }\n\n return $result\n}\n\n# More custom functions would go here\n\n& {\n param(\n [string]$odZoneId,\n [string]$odAction,\n [string]$odName,\n [string]$odResourceAddress,\n [string]$odType,\n [string]$odTtl,\n [string]$odWait,\n [string]$odComment,\n [string]$odAccessKey,\n [string]$odSecretKey\n )\n \n # If AWS key's are not provided as params, attempt to retrieve them from Environment Variables\n if ($odAccessKey -or $odSecretKey) {\n Set-AWSCredentials -AccessKey $odAccessKey -SecretKey $odSecretKey -StoreAs default\n } elseif (([Environment]::GetEnvironmentVariable(\"AWS_ACCESS_KEY\", \"Machine\")) -or ([Environment]::GetEnvironmentVariable(\"AWS_SECRET_KEY\", \"Machine\"))) {\n Set-AWSCredentials -AccessKey ([Environment]::GetEnvironmentVariable(\"AWS_ACCESS_KEY\", \"Machine\")) -SecretKey ([Environment]::GetEnvironmentVariable(\"AWS_SECRET_KEY\", \"Machine\")) -StoreAs default\n } else {\n throw \"AWS API credentials were not available/provided.\"\n }\n\n If($odAction -ne \"CREATE\" -and $odAction -ne \"DELETE\" -and $odAction -ne \"UPSERT\") { throw \"Invalid Action provided. Please use CREATE, DELETE or UPSERT.\" }\n\n if ($odName -notmatch '.+?\\.$') { $odName += '.' }\n\n $change = (New-Object Amazon.Route53.Model.Change)\n $change.Action = $odAction\n $change.ResourceRecordSet = (New-Object Amazon.Route53.Model.ResourceRecordSet)\n $change.ResourceRecordSet.Name = $odName\n $change.ResourceRecordSet.Type = $odType\n $change.ResourceRecordSet.TTL = $odTtl\n \n if ($odResourceAddress -like '*,*') {\n $($odResourceAddress -split ',') | Foreach-Object {\n $change.ResourceRecordSet.ResourceRecords.Add(@{Value=$($_)})\n }\n } else {\n $change.ResourceRecordSet.ResourceRecords.Add(@{Value=$odResourceAddress})\n }\n\n Write-Output (\"------------------------------\")\n Write-Output (\"Checking if Resource Record Set Exists:\")\n Write-Output (\"------------------------------\")\n\n $resourceRecordSetObj = $(Get-R53ResourceRecordSet -HostedZoneId $odZoneId).ResourceRecordSets | Where {$_.Name -eq $odName}\n $resourceRecordSetCount = ($resourceRecordSetObj | measure).Count\n\n if ($odAction -eq \"DELETE\") {\n if ($resourceRecordSetCount -gt 0) {\n Write-Output (\"The record '$($odName)' exists, deleting...\")\n } else {\n Write-Output (\"Cannot Delete: The record '$($odName)' does not exist, skipping...\")\n Exit\n }\n } elseif ($odAction -eq \"CREATE\") {\n if ($resourceRecordSetCount -gt 0) {\n Write-Output (\"Cannot Create: The record '$($odName)' already exists, skipping...\")\n Exit\n } else {\n Write-Output (\"The record '$($odName)' does not exist, creating record...\")\n }\n } elseif ($odAction -eq \"UPSERT\") {\n if ($resourceRecordSetCount -gt 0) {\n Write-Output (\"The record '$($odName)' already exists, updating record...\")\n } else {\n Write-Output (\"The record '$($odName)' does not exist, creating record...\")\n }\n } else { throw \"OMG - Unexpected result\" }\n \n $params = @{\n HostedZoneId=$odZoneId\n ChangeBatch_Comment=$odComment\n ChangeBatch_Change=$change\n }\n\n Write-Output (\"------------------------------\")\n Write-Output (\"Listing DNS change/s to be made:\")\n Write-Output (\"------------------------------\")\n\n $($params.ChangeBatch_Change) | Foreach-Object {\n $resourceRecords=\" | \"\n\n $($_.ResourceRecordSet.ResourceRecords) | Foreach-Object {\n $resourceRecords += $_.Value + \",\"\n }\n\n Write-Output ($($_.Action.Value) + \" | \" + $($_.ResourceRecordSet.Name) + \" | \" + $($_.ResourceRecordSet.Type) + $($resourceRecords -replace \".$\"))\n }\n\n \n\n $timeout = new-timespan -Seconds 30\n $sw = [diagnostics.stopwatch]::StartNew()\n $attempt = 1\n\n while ($true) {\n try {\n $result = Edit-R53ResourceRecordSet @params\n break\n }\n catch [Amazon.Route53.AmazonRoute53Exception] {\n Write-Output (\"$($_.Exception.errorcode)-$($_.Exception.Message)\")\n\n if ($attempt -eq 3) {\n throw $_.Exception.errorcode + '-' + $_.Exception.Message\n }\n\n if ($sw.elapsed -gt $timeout) {throw \"Timed out waiting for 'Edit-R53ResourceRecordSet' to succeed\"}\n\n Write-Output (\"Attempt no.$($attempt) failed - Trying again in 5 seconds...\")\n Sleep -Seconds 5\n\n $attempt++\n }\n }\n\n\n Write-Output (\"------------------------------\")\n Write-Output (\"Checking the R53 Change status:\")\n Write-Output (\"------------------------------\")\n\n $timeout = new-timespan -Seconds 120\n $sw = [diagnostics.stopwatch]::StartNew()\n\n while ($true) {\n $currentState = (Get-R53Change -Id $result.Id).Status\n\n if ($currentState -eq \"INSYNC\") {break}\n if ([bool]($odWait -eq $false)) {break}\n\n Write-Output (\"$(Get-Date) | Waiting for R53 Change '$($result.Id)' to transition from state: $currentState\")\n\n if ($sw.elapsed -gt $timeout) {throw \"Timed out waiting for desired state\"}\n\n Sleep -Seconds 5\n }\n Write-Output (\"$(Get-Date) | R53 Change state: $currentState\")\n } `\n (Get-Param 'odZoneId' -Required) `\n (Get-Param 'odAction' -Required) `\n (Get-Param 'odName' -Required) `\n (Get-Param 'odResourceAddress' -Required) `\n (Get-Param 'odType' -Required) `\n (Get-Param 'odTtl' -Required) `\n (Get-Param 'odWait' -Required) `\n (Get-Param 'odComment') `\n (Get-Param 'odAccessKey') `\n (Get-Param 'odSecretKey')"
},
"Category": "AWS",
"HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/aws-create-a-route-53-resource-record.json",
"Website": "/step-templates/9271327d-6e8a-49d1-881a-3925c75aef56",
"Logo": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAMAAACahl6sAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADNQTFRF////9o0R/eLD/Nu0/erS95Qg+bhr95sv/vHh+r96/vjw+bFc/NSl+KI++82W+saI+KpNeDqM1wAAA41JREFUeNrsnG2XazAURiuo0Cr//9feliIvR3DvXJFZe3+a6XpW5+xWEpyY2w0AAAAAAAAAAAAAAAAAAADgf1J0bda/9N70q83a3enzUHWVjbR1sW0xp6sd6fPI72VmUt3zA+kymD6N5vnIBMrHsxHTjsUXOX0e+iVaTNU5Q0A/Q+k+4oAp+ixMbw6A4rGVVjGHR92ulNXWuTAlBNJN/FFyr5yy3qN9rawmF9IxR4hqX4U1WMplmGtruVBDuiuswbKkzaGhX+cfXsqbZlXXv0dsYR13nw9fLenGXD7f6U5Ony4yTpzyZLNMUcpMr0xNzfwdRRMR1/LP2cqMctNqKx1LZFydm2U022ueEtLL6HbHfmSRYRn4HDXaXyzU4XRkkZWK/+JlRBBBBBFEEEEEEUQQQQQRRBBB5B9uYJc7SyuLw+nI7R2ptKWJcywd18Utza0rnM4iN66M6qzS5E93Lf1zLaviUL/ISs/Nt6W00DEyuRgiP2Yxvrd15z/Y26ncG76jy1Ta5jEy/L0p/VMWy33woVm8UYN1Y9fqKrzfZ5iedtaV34+kNxHak2Wg2SSkY7djx/bQWkNP6nkE0lH3Lyx7D1aak1Z1erWJ+U130Vz0Sude7mZqv995nW7mZxJd27Sg5XQppuMdWY3xl1XXOge8MasWjZfund0KbvrkE9fK7OPNne+2U9YEWX3nemtSbvLv6LJ7gZ9X45yBl9ZxrZ9d3vjT8rz62tOsny7jXkpYPX9jQmvF8yF55TdaslGviZy1vAmfoTobsZztGNEv7qZZSr/6HRc/0yzlb3HiKhURRBBBBBFEEEEEEUQQQQQRRBD5XSLav38tllbVzeH02Ww/UWA+6XgsHdXFKc2vK5Quoz/duVRnlrb26crpizzXOVU3l2Zb5Pfe+d1OX8ViqW7qH9gt51K44bukr2XxrW54vMaoy7mxa/cgvPRVKcQG7uOCD58HLQLt3r17Iy6AqjYeDG7TUenWW+p9Ot/IOF/lwuHV1nk6o8M469PWXhtr+0BeX/x7Ue40W3xacfb2gXFxUZcX8TYB3Kyfp+GThsjKti2zgZuMiLshxW3gpiQyrn/DXhR/i1NqIte5pkUEEUQQQQQRRBBBBBFEEEEEEUR+g4jQUZBEqjqFO9mOiyeShoXvYoukZOG4GCLpWZgu83/vTNRidhlE0rYAAAAAAAAAAAAAAAAAAACAZPkjwAAMDi+bsnPP/wAAAABJRU5ErkJggg==",
"$Meta": {
"Type": "ActionTemplate"
}
}
Page updated on Wednesday, January 31, 2018