Skip to main content

Templates

Define and share common Tasks with your team.

Introduction#

Templates are pre-defined Tasks stored in a Git repository. These special Tasks have variables defined in their scripts.

When creating a Task using a Template, you have to provide only the variables. A regular Task will be created using the Template script filled with the parameters you provide.

You can run a Task from Slack providing the parameters to the Runops bot, get reviews, and get result logs; all without touching a single line of code or command-line. But you can also use the Runops CLI.

Create a Template#

Let's create a Template for querying DynamoDB.

We will create a Template using Python with AWS's boto3 library. After creating the script, we commit it to the main branch of the Runops Templates repository.

pro-tip

Open the Templates repository for everyone at your company to contribute with scripts they already have.

Here is our template, lets save it to a file and commit it to the main branch of a Github repository.

#file: dynamodb-query.py
import boto3
client = boto3.client('dynamodb')
response = client.get_item(
Key={
'{{pk}}': {
'S': '{{pk_value}}',
},
'{{sk}}': {
'S': '{{sk_value}}',
},
},
TableName='{{table}}',
)
print(response)

Connect Runops to Github#

To connect Runops to your Templates repository, add the Github user runopsbot as a read-only collaborator to the repository.

You will soon be able to connect using OAuth from the Runops web app.

Check available templates#

Now we can see the template available. Listing the Templates will read all the files in the main branch of the Github repository:

$ runops templates list
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Name β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ dynamodb-query.py β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Ό
β”‚ other-template-sql β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

To verify specific details about a template, like its params:

$ runops templates get --name dynamodb-query.py
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Attribute β”‚ Value β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ name β”‚ dynamodb-query.py β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ params β”‚ {{pk}} β”‚
β”‚ β”‚ {{pk_value}} β”‚
β”‚ β”‚ {{sk}} β”‚
β”‚ β”‚ {{sk_value}} β”‚
β”‚ β”‚ {{table}} β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Use a Template#

Create a Task from the Template

runops templates run \
--name dynamodb-query \
--target aws-account-prod-a
--params \
table='Music'
pk='Artist', \
pk_value='Acme Band', \
sk='SongTitle'
sk_value='Happy Day'

Use Templates in Slack#

To run templates from Slack, run /runops templates anywhere in your Slack workspace:

Creating Templates#

Templates are very similar to regular Tasks scripts. The only difference is that instead of directly using values in the business logic, we use placeholders.

Placeholders are the parameters of our Template. You will provide these values when creating a Task from a Template.

Parameters are indicated by double curly braces.Β {{person}}Β is a parameter, and we'd refer toΒ personΒ as the key or parameter key. Let's take a look at our DynamoDB query template from the Getting Started guide:

dynamodb-query.py

import boto3
client = boto3.client('dynamodb')
response = client.get_item(
Key={
'{{pk}}': {
'S': '{{pk_value}}',
},
'{{sk}}': {
'S': '{{sk_value}}',
},
},
TableName='{{table}}',
)
print(response)

This template has 5 parameters:

table - the name of the DynamoDB table

pk - the name of the Partition Key

sk - the name of the Sort Key

pk_value- the value of the Partition Key

sk_value - the value of the Sort Key

Workflow#

A powerful workflow for Templates is having a central Git repository with scripts certified by stakeholders of a Target.

Engineers from multiple teams could submit Pull Requests to this repository. After testing, the Template gets merged into the main branch and becomes available to everyone to everyone in the company.

Ignoring files#

A .runopsignore file specifies intentionally untracked files that runops should ignore when listing templates.

Pattern Format#

  • A blank line matches no files
  • A line starting with # serves as a comment
  • Trailing spaces are ignored
  • The slash / is used as the directory separator
  • Using the slash / in the beginning, has a special meaning to indicate matching files in the root of the folder.
  • An asterisk * matches anything

Examples#

  • The pattern hello.* matches any file or directory whose name begins with hello. If one wants to restrict this only to the directory and not in its subdirectories, one can prepend the pattern with a slash, i.e. /hello.*; the pattern now matches hello.txt, hello.c but not a/hello.java.
  • The pattern doc/frotz and /doc/frotz have the same effect in any .runopsignore file. In other words, a leading slash is not relevant if there is already a middle slash in the pattern.
  • The pattern foo/*, matches foo/test.json (a regular file), foo/bar (a directory), and all contents in the subdirectories also, like foo/bar/test.sql.
# ignore all files and folder in the root directory that ends with .sql
/*.sql
# ignore all files and folders in all directories
*.md
# ignore /dev/scripts/.placeholder file
dev/scripts/.placeholder
# ignore all files and folders that ends with .sh or .sql in /dev/scripts folder
dev/scripts/*.[sh|sql]
# ignore all files and folders that begins with config inside /prod/scripts folder
/prod/scripts/config*