RightScale Policies provide a flexible solution for defining arbitrary policies that span across Cost, Security, Compliance, and Operational categories. Policies may analyze data exposed by the RightScale platform or by any other service. Policies can combine and validate data coming from multiple services. When a policy check fails an incident is created which may in turn trigger a sequence of actions. Actions may be automated and may take advantage of RightScale Cloud Workflow. This makes it possible for policies to trigger arbitrarily complex orchestration involving any service.

Policies are written in code making it possible to version, share and reuse parts of policies across multiple use cases. The policy template language is a simple DSL (Domain Specific Language) similar to the RightScale CAT (Cloud Application Template) language. Policy templates describe how to retrieve the data, how to validate it and what to do when a validation check fails.

Check out some sample policies as well as the complete list of RightScale policies.

Syntax

A policy template consists of a sequence of definitions. Definitions may be simple definitions of the form:

<name> <term>

Where <name> is the name of the definition and <term> is a term, for example:

short_description "Limit the total number of VMs running in a project."

Terms can be literal values like in the example above, function calls, certain reserved words or in some cases references to other definitions.

Definitions may also be composite definitions of the form:

<name> <term> [, <property>: <string literal>] do
   <property> <term>
   <property> <term>
   …
end

Where <property> is the name of a definition property, for example:

parameter "max_instances" do
   type "number"
   label "Maximum number of instances"
end

or

resources "instances", type: "rs_cm.instances" do
   cloud_href href(@clouds)
   state "operational"
end

Comments

Comments start with the character #. They may appear at the end of a line or on a new line:

short_description "Limit number of VMs." # Note: only works on cloud X
# Comment on a new line

Functions

Functions make it possible to compute values dynamically, for example by concatenating multiple values together or extracting sub-text from an API response. The syntax for calling a function is:

<name>(<term>, <term>, …)

For example:

href(col_item)

A function may have zero or more parameters. The function reference page lists all the functions available for use in policy templates. The list describes the parameters and return values as well as where the function may be used.

Reserved Words

The Policy Template Language also defines a few reserved words that make it possible to retrieve contextual information or iterate over data collections. The list of complete reserved words and their usage is described in the Reserved Word Reference. For example rs_org_id returns the ID of the RightScale organization.

String Literals

A string literal begins and ends with a double or single-quote mark. Double-quoted string expressions are subject to backslash notation. A single-quoted string expression isn't; except for \' and \.

Backslash Notation

Also called escape characters, backslashes are used to insert special characters in a string.

Example:

"this is a\ntwo line string"
"this string has \"quotes\" in it"
Escape Sequence Meaning
\n newline
\s space
\r carriage return
\t tab
\" double quote character
\' single quote character
\ backslash

Multiline String Literals

Multi-line string literals can be defined with here documents, where the delimiter can be any string:

<<END
on the one ton temple bell
a moon-moth, folded into sleep,
sits still.
END

The syntax begins with << and is followed immediately by the delimiter. To end the string, the delimiter appears alone on a line.

Array Literals

Arrays are defined using square brackets and commas to separate the elements:

["a", "b", "c"]
[1, 2, 3]
["a", [1, "b"]]

Object Literals

Objects are defined using curly braces and colons to separate keys and values:

{
   "a": 1,
   "b": "c",
   "d": [2, 3],
   "e": {
      "f": 4
   }
}

Metadata

The first section of a policy template provides generic information about the policy such as its name, a short and long description as well as the policy severity and category:

name "Instance Quota"
rs_pt_ver 20180301
type "policy"
short_description "Limit the total number of VMs running in a project."
# Optional metadata
long_description <<-EOF
The Instance Quota policy sends an email to developer@company.com when the
number of VMs running in the RightScale project exceeds 1,000.
EOF
severity "medium"
category "Cost"
  • name defines the policy template name. It must be unique in the project.
  • rs_pt_ver indicates the policy template language version. The value must be 20180301.
  • type must be "policy"
  • short_description provides a short description of what the policy does.

The following definitions are optional:

  • long_description is a long description of what the policy does.
  • severity indicates the policy severity, it must be one of "low" (default), "medium", "high" or "critical".
  • category is an arbitrary value used to group policies into categories, for example "Cost", "Compliance" or "Security".

Permissions

Permission definitions list the privileges required to apply the policy. The list must include privileges required to retrieve the data as well as the privileges required to run the policy actions.

Each permission definition can list multiple required privileges. The set is defined by providing a list of resource types and a list of actions that the policy needs to perform on these resources:

permission do
   label "List Instances"
   resources "rs_cm.instances"
   actions "rs_cm.index"
end

permission do
   label "List and delete servers and instances"
   resources "rs_cm.servers", "rs_cm.instances"
   actions "rs_cm.index", "rs_cm.destroy"
end

The complete set of resources and actions as well as the mapping between privileges and roles is listed in the Permission Reference section.

Retrieving Data

The first step performed when a policy is evaluated is to retrieve the data that needs to be validated. There are two ways to retrieve data from a policy template:

  • Resources make it possible to list resources using the RightScale APIs.
  • Datasources make it possible to retrieve data from any arbitrary service.

Datasources can also be used to further process data retrieved from either resources or other datasources as described in Chaining Datasources.

Listing Resources

The resources definition identifies a resource type and an optional set of filters used to list resources:

resources <name>, type: <resource type> do
   filter do
      <filter> <filter comparator> <filter value>
      <filter> <filter comparator> <filter value>
      ...
   end
   <property> <property value>
   <property> <property value>
   ...
end
  • name defines the resource name and must be unique. It can be referenced using @ elsewhere in the code.
  • resource type is the type of resource.
  • filter is the API field to filter on, such as state. If multiple filters are specified it will AND together the results. Only resources which satisfy all the filters will be returned.
  • filter comparator is optional and must be either ne: or eq:. If not specified, it defaults to eq:.
  • filter value is either a term or array of terms. Caution: Only ever specify an array of terms with ne: as the comparator. If you specify it with eq: it will do a logical AND and try and set the filter be equal to ALL the values passed in, which will return no results.
  • property is a property of the resource such as cloud_href or view.
  • property value is value of the property.

The complete list of supported resource types, filters, and properties is described in the Resource Reference.

This example filters returns active Windows instances on AWS clouds. The first resources block filters upon cloud_type to only return AWS regions. The filter comparator is left off and defaults to eq:. The second resources block filters upon the os_platform and state of the instances to get active instances. It can be referenced later in the policy as @instances.

resources "aws_regions", type: "rs_cm.clouds" do
  filter do
    cloud_type "amazon"
  end
end

resources "instances", type: "rs_cm.instances" do
  iterate @aws_regions
  cloud_href href(iter_item)
  filter do
    os_platform "windows"
    state ne: ["stopped", "provisioned", "terminated"]
  end
end

Including tags

You can query for resources by tag using tags field in your resource. You can also use the all, any, none methods to expand your search with tags. Only one tag field is supported per resource.

resources "instances", type: "rs_cm.instances" do
  iterate @aws_regions
  cloud_href href(iter_item)
  tags "ns:name=*"
end

resources "volumes", type: "rs_cm.volumes" do
  iterate @aws_regions
  cloud_href href(iter_item)
  tags any(["ns:name=*","foo:bar=hurray"])
end

# include fields in your datasource
datasource "instances" do
  iterate @instances
  field "href",        href(iter_item)
  field "id",          val(iter_item,'resource_uid')
  field "name",        val(iter_item,'name')
  field "state",       val(iter_item,'state')
  field "type",        "instances"
  field "tags",        val(iter_item,'tags')
end

Additional tag filters examples.

tags "ns:name=*" # Filter by namespace and key
tags "ns:*"      # Filter by namespace only
tags "*"         # Return any resource with a tags
tags any(["ns:name=*","foo:bar=hurray"]) # Resource must include any tag in array.
tags all(["ns:name=*","foo:bar=hurray"]) # Resource must include all tags in array.
tags none(["ns:name=*","foo:bar=hurray"]) # Resource must not include any tags in array

API Data with Datasources

There are three forms of datasource definitions. The first one, discussed here makes it possible to retrieve data from HTTP APIs. The second one, described in the next section makes it possible to use JavaScript to process existing data and the last one described in Chaining Datasources makes it possible to derive a datasource from existing data.

Authorization

Policies can authorize against external APIs using a variety of authorization schemes. The auth definition defines how to perform the authorization and can be referenced when describing a datasource. The syntax of the auth definition is:

auth <name>, type: <type> do
   <property> <term>
   <property> <term>
   ...
end

Where:

  • <name> is the name of the scheme.
  • <type> is the type of the scheme.

The properties used to define a scheme depends on its type. See the Authorization Reference section for a description of the available authorization schemes and their properties.

Example:

auth "aws_us_east_1", type: "aws" do
  version    4
  service    "ec2"
  region     "us-east-1"
  access_key cred("AWS_ACCESS_KEY_ID")
  secret_key cred("AWS_SECRET_ACCESS_KEY")
end

Pagination

If results from a custom datasource are paginated, you must define a pagination block above your datasource that describes how to extract the next page token from a response and where to insert the token into subsequent queries.

pagination <name> do
  get_page_marker do
    body_path <path expression>
    header <header name>
  end
  set_page_marker do
    query <query param name>
    header <header name>
    uri <true|false>
  end
  • <name> is the name of the paginator. The name can be referred to in the pagination field of datasource request blocks with a $ in front.
  • <path expression> is a JMESPath (if the encoding of the request is JSON) or XPath expression (if the encoding is XML) describing how to extract the page token from the body.
  • <header name> is the name of the http header containing the page token.
  • <query param name> is the name of the query string parameter to set.
  • uri should be set to true if the page token marker is a full URL, such as a nextLink attribute returned by Azure ARM services.

For get_page_marker exactly one of body_path or header must be set. For set_page_marker exactly one of query, header, or uri must be set.

AWS API requests contain a variable in the response body called PageToken. This variable should be set as a HTTP query parameter NextToken to subsequent requests. AWS supports both XML and JSON encoding. The datasource definition has an encoding of xml below so an XPath expression is used for the body_path.

pagination "aws_pagination_xml" do
  get_page_marker do
    body_path "//PageToken"
  end
  set_page_marker do
    query "NextToken"
  end
end

This is the same paginator except for JSON data.

pagination "aws_pagination_json" do
  get_page_marker do
    body_path "PageToken"
  end
  set_page_marker do
    query "NextToken"
  end
end

The following service has a X-Page-Token header that it both returns and expects:

pagination "my_service" do
  get_page_marker do
    header "X-Page-Token"
  end
  set_page_marker do
    header "X-Page-Token"
  end
end

The following service contains a nextLink parameter in the body that is a full URL to the next page of results. It is assumed that the datasource will specify we want JSON encoding.

pagination "azure_arm_pagination_json" do
  get_page_marker do
    body_path "nextLink"
  end
  set_page_marker do
    uri true
  end
end

Request

The syntax of a datasource that retrieved data from an HTTP API is:

datasource <name> do
   request do
      auth $<auth definition>
      pagination $<pagination definition>
      host <host>
      verb ["GET"|"POST"]     # defaults to "GET"
      scheme ["http"|"https"] # defaults to "https"
      path <path>
      ignore_status [<http status code>, <http status code>...]
      query <query string name>, <query string value>
      query <query string name>, <query string value>
      ...
      header <header name>, <header value>
      header <header name>, <header value>
      ...
      body_field <body field name>, <body field value>
      body_field <body field name>, <body field value>
      ...
   end
   result
      encoding ["json"|"xml"]
      [collect xpath(response, <xpath>) do]
      [collect jmes_path(response, <jmes_path>) do]
      field <field name>, <term>
      field <field name>, <term>
      ...
      [end]
   end
end

Where:

  • <name> is the name of the datasource.
  • <auth definition> is the name of the auth definition that describes how to sign requests made to the API if any.
  • <pagination definition> is the name of the pagination definition that describes how to iterate through the response pages if any.
  • <host> is the API hostname.
  • <verb> is the HTTP request method and defaults to "GET".
  • <path> is the HTTP path
  • <ignore_status> are http status codes to ignore failure on. Normally any status code other than 200-299 will cause the policy to stop evalaution and return a failure. Supply a list of values or a list parameter such as [403, 404] to cause the policy to treat these calls as an empty dataset and continue running.
  • <query string name> and <query string value> describe the request query string elements if any.
  • <header name> and <header value> describe any additional headers you wish to send with the API request.
  • <body field name> and <body field value> describe the body JSON object fields if any.

Note: only JSON encoding is supported in the REQUEST body at this time.

Result

The result property details how to parse the HTTP response to produce the resulting data. The properties are:

  • encoding: specifies the response encoding, must be "json" or "xml".
  • field: identifies a field in the resulting data. The provided term is evaluated to initialize the field value. Typically the term is either the jmes_path or xpath function.

result may also make use of collect to iterate over the response elements. collect accepts a term and a block. The term must be xpath or jmes_path. The term must return an array which collect iterates over. Each element of the array can then be used to define the data fields. The current element is accessed using the col_item reserved word as shown in the example below.

datasource "volumes_us_east" do
  request do
    auth                      $aws_auth_us_east_1
    pagination                $aws_pagination_xml
    host                      "ec2.amazonaws.com"
    query "Action",           "DescribeVolumes"
    query "Filter.1.Name",    "encrypted"
    query "Filter.1.Value.1", "false"
    header "User-Agent" "My-app"
  end
  result do
    encoding "xml"
    collect xpath(response, "/DescribeVolumesResponse/volumeSet/item") do
      field "id", xpath(col_item, "volumeId")
      field "region", "us-east-1"
      field "size", xpath(col_item, "size")
      field "type", xpath(col_item, "volumeType")
      field "tag_set" do
        collect xpath(item, "tagSet") do
          field "key", xpath(col_item, "key")
          field "value", xpath(col_item, "value")
        end
      end
    end
  end
end

Processing Datasources With JavaScript

Datasources may use JavaScript to combine and transform data from one or more datasources to create a new datasource. The syntax used in this case is:

datasource <name> do
   run_script $<script>[, <term>]*
end

Where <script> is the name of script definition and the terms are parameters or datasources given to the script for execution. The script result defines the data returned by the datasource. Terms can be any type (including other datasources, which will show up as arrays of JavaScript Objects).

Scripts are defined using script definitions with the following syntax:

script <name>, type: "javascript" do
  parameters <string literal>[, <string literal]*
  result <string literal>
  code <string literal>
end

parameters is the list of parameters to pass it to the script. The parameters will automatically be set as JavaScript variables at the start of script execution.

result identifies the name of the JavaScript variable used to extract the data returned by the script. result is required.

code contains the actual JavaScript code. code is required.

Example:

datasource "add" do
   run_script $add, size($instances_us_east), size($security_groups_us_east)
end

script "add", type: "javascript" do
  parameters "a", "b"
  result "res"
  code <<-EOS
  res = a + b
  EOS
end

For more complicated examples of JavaScript datasources including scripts that combine together multiple datasources see policy examples such as the open ports policy

Chaining Datasources

A Datasource describes one type of API call. However, sometimes multiple levels of requests need to be made if you have a resource that is a subresource to another resource. For example, a policy validating that there are no publicly accessible S3 buckets must first fetch all the bucket names then fetch the ACLs for each bucket. In this case a datasource definition can reference a resources definition or another datasource definition. The syntax used to refer to a resources definition is @<resource definition name> and the syntax used to refer to another datasource definition is $<datasource definition name>. For example:

resources "clouds", type: "rs_cm.clouds"

resources "instances", type: "rs_cm.instances" do
   iterate @clouds            # iterate through the data retrieved by the
                              # "clouds" resource definition.

   cloud_href href(iter_item) # iter_item returns the cloud data currently
                              #  being iterated on.
end

Note: iterate may appear only once in a given datasource definition.

As shown in the example above references are typically used together with the iterate reserved word to iterate over the elements of the data. If the data is not an array then iterate takes care of wrapping it with a single element array.

References may also be used directly as argument of other functions such as val, href, size or select.

Finally, references can be used when defining the parameters given to run_script:

datasource "permissions" do
   run_script "get_permissions", @instances, @security_groups
end

Describing the Policy Conditions

Now that we know how to retrieve the data the next step consists of actually writing the conditions they must validate. This is done in the policy definition. There can be only one such definition in a given policy template.

A policy definition consists of a list of validations. Each validation may in turn describe multiple checks. A validation also defines one or more escalations that trigger when a check fails and resolutions that trigger when an underlying issue is fixed. Finally a validation also provides a default summary and details text templates used to render the incident message.

The syntax for a policy definition is:

policy <string literal> do
  validate[_each] $<datasource>|@<resources> do
    summary_template <string literal>
    detail_template <string literal>
    escalate $<escalation>
    escalate $<escalation>
    resolve $<resolution>
    resolve $<resolution>
    ...
    check <term>
    check <term>
    ...
  end
  validate...
end

Where:

  • Each validation starts with validate or validate_each.
    • validate applies the checks on the given datasource or resources as a whole.
    • validate_each iterates over the given datasource or resources (which must be an array or is wrapped into a single element array) and applies the checks on each element.
  • summary_template provides a text template that gets applied to the escalation data to render the incident message summary.
  • detail_template provides a text template that gets applied to the escalation data to render the incident message details.
  • escalate indicates an escalation to trigger when a check fails.
  • check identifies a term that must return anything BUT false, 0, an empty string, an empty array or an empty object. If the term returns one of these values then the check fails, an incident is created and any associated escalation triggers.

The policy engine runs each check in order and stops when a check fails. A check fails if the corresponding term returns false, 0, an empty string, an empty array or an empty object. In the case of validate_each the policy engine applies that algorithm for each element of the datasource or resources.

Each time a check fails the corresponding data is added to the escalation data. In the case of validate this can only happen once and thus the escalation data ends up being the validated datasource or resources. In the case of validate_each this means that only the elements that fail a check are added to the escalation data.

Example:

policy "ri_expiration" do
  validate_each $reservations do
    summary_template "Reserved instances are nearing expiration."
    detail_template <<-EOS
Reserved Instance Expiration
{{ range data }}
* Account: {{ .account_name }}({{ .account_id }})
* Region: {{.region}}
* Instance Type: {{.instance_type}}
* Instance Count: {{.instance_count}}
* End Time: {{.end_time}}
----------------------------
{{ end }}
EOS
    escalate $alert
    check gt(dec(to_d(val(item, "end_time")), now), 3*24*3600))
  end
end

In the example above the policy defines a single validation with a single check. The check returns a boolean value which is false when the duration between a reserved instance expiration data and now is less than 3 days. In this case the alert escalation triggers. The escalation data consists of an array that contains all the reservations that are expiring in less than 3 days.

Escalations

Escalation definitions describe a sequence of actions to be taken when a policy fails to validate.

Syntax:

escalation <string literal> do
   email <term> do
      subject_template <string literal>
      body_template <string literal>
   end
   request_approval do
     label <string literal>
     description <string literal>
     parameter <string literal> do
       type ["string"|"list"|"number"]
       label <string literal>
       index <unsigned integer>
       category <string literal>
       description <string literal>
       default <any value>
       no_echo <boolean>
       allowed_values <any value> [, <any value>]
       min_length <unsigned integer>
       max_length <unsigned integer
       min_value <floating point number>
       max_value <floating point number
       allowed_pattern <regular expression>
       constraint_description <string literal>
     end
   end
   run <string literal>[, <term>]*
end

Both the email and run sections can appear 0 or more times in any order.

  • email causes an email to be sent to the given address. The term may be a reference to a parameter or any of the applicable functions. The email definition makes it possible to use text templates to define the content of the subject and body. See the Templates section for more information.
  • run launches a Cloud Workflow using the given RCL definition. The RCL definition may be given parameters specified in a comma separated list. Parameters may be references or any of the applicable functions.
  • request_approval creates an approval request and blocks further actions from executing until a user approves or denies the action. Parameters can be referenced by subsequent cloud workflows or emails within the same escalation.

Example:

define handle_unencrypted_volumes($data, $tags) return $jira_ticket_id do
  # RCL code omitted for brevity
end

escalation "handle_unencrypted_volumes" do
  request_approval  do
    label "Escalation approval"
    description "Approve handle_unencrypted_volumes action"
    parameter "approval_reason" do
      type "string"
      label "Reason for approval"
      description "Explain why you are approving the action"
    end
  end

  run "handle_unencrypted_volumes", data, $enforced_tags

  email $escalate_to do
    subject_template "Unencrypted volumes found in project {{ rs_project_name }}"
    body_template <<-EOS
Unencrypted Volumes
The following volumes are tagged with one of the tags shown below and are unencrypted:
{{ range $index, $tag := parameters.enforced_tags }}{{ if $index }}, {{ end }}{{ $tag }}{{ end }}
{{ range data }}
* Region: {{ .region }}
* Volume ID: {{ .id }}
* Volume Tags: {{ .tag_set }}
{{ end }}

[JIRA Ticket]({{ parameters.jira_url }}/{{ data.jira_ticket_id }})

EOS
end

Resolutions

Resolutions definitions describe a sequence of actions to be taken when a failing policy is resolved. Resolved means that the underlying checks which caused the policy to go into a failed state have been been corrected, either by escalation actions or by manual intervention. Resolutions may not happen as soon as the condition is fixed; conditions are checked on a schedule (typically 15 minutes) chosen when the policy is applied. An incident resolves under two scenarios:

  • The policy runs at it's next scheduled time and all the items in the previous run's incident are cleared.
  • The resolve_incident function is called.

Syntax:

resolution <string literal> do
   email <term> do
      subject_template <string literal>
      body_template <string literal>
   end
   request_approval do
     label <string literal>
     description <string literal>
     parameter <string literal> do
       type ["string"|"list"|"number"]
       label <string literal>
       index <unsigned integer>
       category <string literal>
       description <string literal>
       default <any value>
       no_echo <boolean>
       allowed_values <any value> [, <any value>]
       min_length <unsigned integer>
       max_length <unsigned integer
       min_value <floating point number>
       max_value <floating point number
       allowed_pattern <regular expression>
       constraint_description <string literal>
     end
   end
   run <string literal>[, <term>]*
end

Both the email and run sections can appear 0 or more times in any order. Resolutions have the same syntax as escalations.

  • email causes an email to be sent to the given address. The term may be a reference to a parameter or any of the applicable functions. The email definition makes it possible to use text templates to define the content of the subject and body. See the Templates section for more information.
  • run launches a Cloud Workflow using the given RCL definition. The RCL definition may be given parameters specified in a comma separated list. Parameters may be references or any of the applicable functions.
  • request_approval creates an approval request and blocks further actions from executing until a user approves or denies the action. Parameters can be referenced by subsequent cloud workflows or emails within the same escalation.

Example:

resolution "handle_unencrypted_volumes" do
  email $escalate_to do
    subject_template "Unencrypted volumes resolved in project {{ rs_project_name }}"
    body_template <<-EOS
Unencrypted volumes have all been encrypted or deleted.
EOS
end

Incident Message and Email Templates

The Policy Template Language makes it possible to use text templates to define the content of messages shown to users when an incident is created both in the UI and in emails.

Templates have access to the escalation data via the built-in data function. They also have access to the policy template parameter values via the parameters function. Other functions listed below provide access to contextual information such as the RightScale organization and project. The output of the template is interpreted as markdown before being rendered into HTML.

The complete list of functions available to templates is:

  • data: The policy escalation data.
  • parameters: The applied policy parameter values as a hash.
  • rs_org_id: The RightScale organization ID where the policy is applied.
  • rs_org_name: The RightScale organization name where the policy is applied.
  • rs_project_id: The RightScale project ID where the policy is applied.
  • rs_project_name: The RightScale project name where the policy is applied.
  • rs_cm_host: The RightScale Cloud Management API hostname.
  • rs_ss_host: The RightScale Self-Service API hostname.
  • rs_optima_host: The RightScale Optima API hostname.

Text Template Syntax Overview

Control structures in templates are delimited by {{ and }}. For example the following template:

"Project {{ rs_project_id }}: {{ rs_project_name }}"

produces Project 123: foo where 123 is the ID of the RightScale project and foo is its name.

If a control structure left delimiter is followed immediately by a minus sign and space character ({{-), all trailing white space is trimmed from the immediately preceding text. Similarly, if the right delimiter is preceded by a space and minus sign (-}}), all leading white space is trimmed from the immediately following text. The following template produces the same ouput as the previous one:

<<EOS
Project
  {{- rs_project_id }}:
  {{- rs_project_name }}
EOS

Elements of an object or hash are accessed using ., for example the following prints the value of the field name in the escalation data:

"{{ data.name }}"

If the escalation data is an array then the values can be iterated over using the function range:

<<EOS
{{ range data -}}
* "{{ .name }}"
{{ end -}}
EOS

Note how the fields of the current element are accessed using .<name-of-field>. range supports an alternative syntax that makes it possible to access the index and the current element explicitly:

<<EOS
{{ $index, $elem := range data -}}
{{ $index }}. "{{ $elem.name }}"
{{ end -}}
EOS

You may want to include your result in a table. Below is an example how to build a table from the data array.

| Name | Cloud | Status |
| ---- | ----- | ------ |
{{ range data -}}
| {{ .name }} | {{ .cloud }} | {{ .status }} |
{{ end -}}
EOS

Control structures may also test the value of data for conditional output, for example:

<<EOS
{{- if .data.email }}
Email: {{ data.email }}
{{- end }}
EOS

A condition is true if it evaluates to anything other than false, 0, an empty string, array or data structure. There is also a set of binary comparison operators defined as functions:

  • eq returns true if arg1 == arg2
  • ne returns true if arg1 != arg2
  • lt returns true if arg1 < arg2
  • le returns true if arg1 <= arg2
  • gt returns true if arg1 > arg2
  • ge returns true if arg1 >= arg2

Reserved Word Reference

The reserved words are defined below

rs_org_id

rs_org_id returns the numerical identifier for RightScale Organization, that the account belongs to which is currently running the policy. It can be used any place a term can be used.

rs_org_name

rs_org_name returns the name of the RightScale Organization Name that the account belongs, which is currently running the policy. It can be used any place a term can be used.

rs_project_name

rs_project_name returns the name of the RightScale account that is currently running the policy. It can be used any place a term can be used.

rs_project_id

rs_project_id returns the numerical identifier of the RightScale account that is currently running the policy. It can be used any place a term can be used.

rs_cm_host

rs_cm_host returns the RightScale CloudManagement endpoints.

rs_optima_host

rs_optima_host returns the RightScale Optima endpoint.

rs_ss_host

rs_ss_host returns the RightScale Self-Service endpoints.

data

data is used in a policy validate to refer to the whole datasource structure.

item

item is used in a policy validate_each to refer to each item element in the datasource

response

response is used to refer to the response XML or JSON data in a datasource result

iter_item

iter_item is used to refer to each item when doing iterate in a resource or datasource

iter_index

iter_index is the index of each item when doing iterate in a resource or datasource

col_item

col_item is used to refer to each item when doing a collect in a datasource

col_index

col_index is the index of each item when doing a collect in a datasource

Resource Reference

The following table lists all the resources supported by the policy template language. For each resource the table lists the available filters as well as other available properties. Required properties are marked with (*).

Resource Filters Properties Docs
rs_cm.alert alert_spec_href
status
view Alerts
rs_cm.alert_spec description
escalation_name
name
subject_href
instance_href
server_href
server_array_href
server_template_href
view
with_inherited
AlertSpecs
rs_cm.cloud cloud_type
description
name
view Clouds
rs_cm.credential description
name
view Credentials
rs_cm.datacenter name
resource_uid
view Datacenters
rs_cm.deployment description
name
resource_group_href
server_tag_scope
cloud_href(*)
view
Deployments
rs_cm.image cpu_architecture
description
image_type
name
os_platform
resource_uid
visibility
cloud_href(*)
view
Images
rs_cm.instance datacenter_href
deployment_href
name
os_platform
parent_href
placement_group_href
private_dns_name
private_ip_address
public_dns_name
public_ip_address
resource_uid
server_template_href
state
cloud_href(*)
view
Instances
rs_cm.instance_type cpu_architecture
description
name
resource_uid
cloud_href(*)
view
InstanceTypes
rs_cm.ip_address deployment_href
name
cloud_href(*) IpAddresses
rs_cm.network cidr_block
cloud_href
deployment_href
name
resource_uid
view Networks
rs_cm.network_gateway cloud_href
network_href
name
NetworkGateways
rs_cm.placement_group cloud_href
deployment_href
name
state
view PlacementGroups
rs_cm.resource_group cloud_href
name
state
ResourceGroups
rs_cm.route_table cloud_href
name
network_href
view RouteTables
rs_cm.routes cloud_href
description
network_href
next_hop_href
next_hop_ip
next_hop_type
next_hop_url
state
route_table_href(*) Routes
rs_cm.security_group deployment_href
name
network_href
resource_uid
cloud_href(*) SecurityGroups
rs_cm.security_group_rule security_group_href
view
SecurityGroupRules
rs_cm.server cloud_href
deployment_href
name
Servers
rs_cm.server_array cloud_href
deployment_href
name
view ServerArrays
rs_cm.ssh_key resource_uid
name
cloud_href(*)
view
SshKeys
rs_cm.subnet datacenter_href
instance_href
resource_uid
name
network_href
visibility
cloud_href(*) Subnets
rs_cm.user email
first_name
last_name
Users
rs_cm.volumes datacenter_href
deployment_href
resource_uid
name
description
parent_volume_shapshot_href
cloud_href(*)
view
Volumes
rs_cm.volume_attachment instance_href
resource_uid
volume_href
cloud_href(*)
view
VolumeAttachments
rs_cm.volume_snapshot state
deployment_href
resource_uid
name
description
parent_volume_shapshot_href
visibility
cloud_href(*)
view
VolumeSnapshots
rs_cm.volume_type name
resource_uid
cloud_href(*)
view
VolumeTypes

Authorization Reference

The following table lists all the authorization schemes supported by the Policy Template Language. For each scheme the table lists the corresponding properties. Required properties are marked with (*).

AWS

AWS authentication provides ways to authenticate against arbitrary AWS services. Service and region can be omitted or set to inferred to let the signer determine them automatically from the request URL, allowing a single auth definition to work across multiple AWS services and their regions.

Scheme Properties Example
aws version: Signature version, must be 3 or 4 (default). 4
service: AWS canonical service name. "ec2"
region: AWS canonical region name. "us-east-1"
access_key(*): AWS access key ID. cred("AWS_ACCESS_KEY_ID")
secret_key(*): AWS secret access key. cred("AWS_SECRET_ACCESS_KEY")

Example code block:

auth "my_aws_auth", type: "aws" do
  version 4
  service "ec2"
  region "us-east-1"
  access_key "AKIAFOOBARBAZ"
  secret_key cred("AWS_SECRET_ACCESS_KEY")
end

AWS STS

AWS STS authentication provides ways to authenticate against arbitrary AWS services using the AWS Security Token Service. Service and region can be omitted or set to inferred to let the signer determine them automatically from the request URL, allowing a single auth definition to work across multiple AWS services and their regions.

Scheme Properties Example
aws_sts version: Signature version, must be 3 or 4 (default). 4
service: AWS canonical service name. "s3"
region: AWS canonical region name. "us-east-1"
access_key(*): AWS access key ID. cred("AWS_ACCESS_KEY_ID")
secret_key(*): AWS secret access key. cred("AWS_SECRET_ACCESS_KEY")
role_arn(*): Amazon Resource Name (ARN) of the role to assume. "arn:aws:iam::031a1f6c8,:role/test-role"
role_session_name(*): Identifier for the assumed role session. "open_buckets_policy"
policy_json: Restrictive IAM policy in JSON format. "{Version: "2012-10-17"...}"
external_id: Unique identifier that might be required when assuming a role in another account. "c4202e1830"

Example code block:

auth "my_aws_auth", type: "aws" do
  version 4
  service 's3'
  access_key cred('AWS_ACCESS_KEY_ID')
  secret_key cred('AWS_SECRET_ACCESS_KEY')
  role_arn 'arn:aws:iam::031a1f6c8,:role/test-role'
  role_session_name 'open_buckets_policy'
  policy_json <<-EOS
  {
    "Version": "2012-10-17",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": "s3:*",
        "Resource": "*"
      }
    ]
  }
  EOS
  external_id 'unique_id_assigned_by_example_corp'
end

Basic

Basic authentication performs basic HTTP authentication using a Authorization: Basic header.

Scheme Properties Example
basic username(*): Username for basic authentication. "myuser"
password(*): Password for basic authentication. cred("MY_API_PASSWORD")

Example code block:

auth "my_basic_auth", type: "basic" do
  username "user"
  password cred("THE_PASSWORD")
end

API Key

API Key authentication authenticates using an static API Key. It can set a header or query parameter on an http request depending on configuration options.

Scheme Properties Example
api_key key(*): API Key. cred("MY_SECRET_KEY")
location(*): Location of auth field. header or query. "header"
field(*): Header or query param field to set. "Authorization"
type(*): Type of authorization header, prefixes the key value. "Bearer"

Example code block:

auth "my_api_key_auth", type: "api_key" do
  location "header"
  field "Authorization"
  type "Bearer"
  key cred("MY_API_KEY")
end

JWT

JWT authenticates using a Java web token retrieved from a login endpoint. Either basic auth or an API key can be used to retrieve the JWT. Set the basic_auth_username and basic_auth_password fields to use basic auth or the api_key field to use an API key. It is an error to specify both. If neither is specified then the request to retrieve the token is not signed.

Scheme Properties Example
jwt token_url(*): URL from which to retrieve the token. Either basic_auth or API key will be used. "https://web.url/login"
additional_headers: Additional headers to send with the request to retrieve the jwt token. additional_headers do {<br> "API-Version": "1.0"<br> "X-Account": "700"<br> }
api_key: API Key, if used. cred("MY_SECRET_KEY")
location: Location of authorization if API Key is used. Allowed values: header, query. "header"
field: Header or query param field to set if API Key is used. "Authorization"
type: Type of authorization header, prefixes the key value, if API Key is used "Bearer"
basic_auth_username: Username for basic authentication, if used. "myuser"
basic_auth_password: Password for basic authentication, if used. cred("MY_API_PASSWORD")

Example code block:

auth "my_jwt_auth", type: "jwt" do
  api_key cred("MY_API_KEY")
  token_url "https://web.url/login"
  location "header"
  field "Authorization"
  type "Bearer"
  additional_headers do {
    "X-Account": to_s(rs_project_id),
    "User-Agent": $user_agent_from_param,
    "Accept": "text/plain"
  } end
end

OAuth2

OAuth2 authenticates using a OAuth2 access token retrieved from a login endpoint. OAuth endpoints can be authenticated using Client Credentials, a Refresh Token, or JWT token set in the Bearer field.

Scheme Properties Example
oauth2 token_url(*): OAuth 2 endpoint. "https://web.url/login/oauth2"
grant type(*): client_credentials or jwt_bearer or refresh_token grant type:"client_crendentials" do
params...
end

OAuth2 Client Credentials

OAuth2 client credentials can use either a client_id/client_secret combo which client_id and client_secret form parameters, or a client_user, client_password combo which sets a basic authentication header. Client credential authentication can be used to authenticate against various Azure APIs.

Scheme Properties Example
client_credentials client_id: Client ID sent as form parameter, if used. "abc123"
client_secret: Client Secret sent as form parameter, if used cred("OAUTH2_SECRET")
client_user: Username for basic authentication, if used. "myuser"
client_password: Password for basic authentication, if used. cred("MY_API_PASSWORD")
additional_headers: Additional headers to send with authentication request. additional_headers do {<br> "API-Version": "1.0"<br> "X-Account": "700"<br> }
additional_params: Additional form params to send with authentication request. additional_params do {<br> "resource": "https://management.azure.com/"<br> }
scopes: List of scopes used to create access token. ["api:read", "api:write"]

Example code block:

auth "my_oauth2_client_credentials_auth", type: "oauth2" do
  token_url $token_url
  grant type: "client_credentials" do
    additional_headers do {
      "X-Account" => "60073"
    } end
    additional_params do {
      "please" => "yes"
    } end
    client_id "123"
    client_secret cred("JWT_CLIENT_SECRET")
  end
end

Example Azure ARM client credentials:

parameter "tenant" do
  type "string"
  label "Tenant"
  description "ARM Tenant ID"
  default "mytenantname.onmicrosoft.com"
end

auth "azure_arm", type: "oauth2" do
  token_url join(["https://login.windows.net/",$tenant,"/oauth2/token"],"")
  grant type: "client_credentials" do
    additional_params do {
      "resource":  "https://management.azure.com/"
    } end
    client_id cred("ARM_CLIENT_ID")
    client_secret cred("ARM_CLIENT_SECRET")
  end
end

OAuth2 Refresh Token

OAuth2 refresh token fetches access token using a refresh token and client credentials set via a basic auth header.

Scheme Properties Example
refresh_token token(*): Refresh token to use. cred("MY_REFRESH_TOKEN")
client_user: Client user for basic authentication. "abc123"
client_password: Client password for basic authentication. cred("CLIENT_PASSWORD")
additional_headers: Additional headers to send with authentication request. additional_headers do {<br> "API-Version": "br> "X-Account": "700"<br> }
scopes: List of scopes used to create access token. ["api:read", "api:write"]

Example code block:

auth "my_oauth2_refresh", type: "oauth2" do
  token_url "https://us-3.rightscale.com/api/oauth2"
  grant type: "refresh_token" do
    additional_headers do {
      "X-Account": to_s(inc(1, 2))
    } end
    client $my_basic_auth
    token cred("MY_TOKEN")
    scopes "read", "write", "update", "delete"
  end
end

OAuth2 JWT Bearer

OAuth2 JWT Bearer crafts and signs Java web tokens and sets the resulting token in Authorization: Bearer header.

Scheme Properties Example
jwt_bearer iss(*): Issuer of token "1234@developer.gserviceaccount.com"
signing_key(*): Key used to sign JWT token cred("MY_SIGNING_KEY")
sub: Subject of token "1234@developer.gserviceaccount.com"
aud: Intended audience, defaults to token_url "myuser"
alg: Crytographic algorithm used. "RS256"
max_minutes: Max minutes before refreshing token. 60
additional_headers: Additional headers to send with authentication request. additional_headers do {<br> "API-Versi0"<br> "X-Account": "700"<br> }
additional_claims: Additional claims to put in the JWT. additional_claims do {<br> "scope":"https://www.googleapis.com/auth/prediction"<br> }
scopes: List of scopes used to create JWT token. ["api:read", "api:write"]

Example code block:

auth "my_oauth2_jwt_bearer_auth", type: "oauth2" do
  token_url "https://www.googleapis.com/oauth2/v4/token"
  grant type: "jwt_bearer" do
    iss cred("GC_ACCOUNT_EMAIL")
    signing_key cred("GC_PRIVATE_KEY")
    alg "RS512"
    max_minutes 90
    aud "https://www.googleapis.com/oauth2/v4/token"
    additional_headers do {
      "Some-Header" => "Some Value"
    } end
    additional_claims do {
      "scope": "https://www.googleapis.com/auth/prediction"
    } end
    scopes ["https://www.googleapis.com/auth/admin.datatransfer.readonly"]
  end
end