Manifests

Manifests are declarative YAML files describing the configuration of a collection of resources. If you’re familiar with Amazon’s cloudformation, these are like cloudformation templates with a cleaner and more flexible syntax. Shepherd uses Jinja2 templating for handling variables, which results in a very familiar syntax for developers and system administrators comfortable with Ansible.

Basic Structure

A standard valid manifest file consists of 3 root keys:

  1. resources
  2. vars
  3. includes

Along with the above 3 root keys, manifest are parsed utilizing Jinja2 templating. Which allows variables in vars to used in

Resources

(Required)

The resources value is a dict where each key is the name of different resource (local to the manifest namespace). Each resource is also a dict providing the required parameters needed to build the required Resources Object, as such validation of each resource dict is limited to whether it is valid YAML and further validation occurs at Resource initialization.

Vars

(Optional)

The vars value is also a dict where each key is a variable name and the value is the value to be inserted. This dictionary is used by the Jinja2 templating to replace variables in the resource dict.

Includes

(Optional)

In order to break up potentially large manifests the include value is a list of files to include in the current manifest. The included files must still have the same valid format as the root manifest and are merged in where duplicates give priority to the current manifest over the included one.

Summary

A sample main file might look like

---
includes:
  - common-vars.yml

vars:
  instance_type: t1.micro

resources:
  WebServer:
    provider: aws
    type: Instance
    image_id: '{{ webserver_ami }}'
    instance_type: '{{ instance_type }}'
    key_name: '{{ key_name }}'
    user_data: |
      #!/bin/bash
      echo "initializing stack"
    security_groups:
      - WebServerSecurityGroup

  WebServerSecurityGroup:
    provider: aws
    type: SecurityGroup
    group_description: Enable HTTP access via port 80

  WebserverHTTPIngress:
    provider: aws
    type: SecurityGroupIngress
    group_name: WebServerSecurityGroup
    cidr_ip: 0.0.0.0/0
    from_port: '80'
    ip_protocol: tcp
    to_port: '80'

  WebserverSSHIngress:
    provider: aws
    type: SecurityGroupIngress
    group_name: WebServerSecurityGroup
    cidr_ip: 0.0.0.0/0
    from_port: '22'
    ip_protocol: tcp
    to_port: '22'

and the supporting common-vars.yml could look like

vars:
  instance_type: t1.micro
  webserver_ami: ami-abcd1234
  db_name: MyDatabase
  db_password: null
  db_root_password: null
  db_username: null
  key_name: null

YAML

While shepherd may support other formats in the future, we formally support YAML format for manifests. We believe YAML to be more readable than JSON and more flexible that INI config files. With that said there are a few gotchas and awkward features. For the most part the Ansible documentation has a very good summary of the most common YAML gotchas here. In addition a very useful feature in YAML is multiline strings, which are demonstrated in the WebServer['user_data'] in the sample manifest above.