# Deployment Manager Design ## Overview Deployment Manager (DM) is a service that runs in a Kubernetes cluster, supported by a command line interface. It provides a declarative `YAML`-based language for configuring Kubernetes resources, and a mechanism for deploying, updating, and deleting configurations. This document describes the configuration language, the API model, and the service architecture in detail. ## Configuration Language DM uses a `YAML`-based configuration language with a templating mechanism. A configuration is a `YAML` file that describes a list of resources. A resource has three properties: * `name`: the name to use when managing the resource * `type`: the type of the resource being configured * `properties`: the configuration properties of the resource Here's a snippet from a typical configuration file: ``` resources: - name: my-rc type: ReplicationController properties: metadata: name: my-rc spec: replicas: 1 ... - name: my-service type: Service properties: ... ``` It describes two resources: * A replication controller named `my-rc`, and * A service named `my-service` ## Types Resource types are either primitives or templates. ### Primitives Primitives are types implemented by the Kubernetes runtime, such as: * `Pod` * `ReplicationController` * `Service` * `Namespace` * `Secret` DM processes primitive resources by passing their properties directly to `kubectl` to create, update, or delete the corresponding objects in the cluster. (Note that DM runs `kubectl` server side, in a container.) ### Templates Templates are abstract types created using Python or [Jinja](http://jinja.pocoo.org/). A template takes a set of properties as input, and must output a valid `YAML` configuration. Properties are bound to values when a template is instantiated by a configuration. Templates are expanded before primitive resources are processed. The configuration produced by expanding a template may contain primitive resources and/or additional template invocations. All template invocations are expanded recursively until the resulting configuration is a list of primitive resources. (Note, however, that DM preserves the template hierarchy and any dependencies between resources in a layout that can be used to reason programmatically about the structure of the resulting collection of resources created in the cluster, as described in greater detail below.) Here's an example of a template written in [Jinja](http://jinja.pocoo.org/): ``` resources: - name: {{ env['name'] }}-service type: Service properties: prop1: {{ properties['prop1'] }} ... ``` As you can see, it's just a `YAML` file that contains expansion directives. For more information about the kinds of things you can do in a Jinja based template, see [the Jina documentation](http://jinja.pocoo.org/docs/). Here's an example of a template written in Python: ``` import yaml def GenerateConfig(context): resources = [{ 'name': context.env['name'] + '-service', 'type': 'Service', 'properties': { 'prop1': context.properties['prop1'], ... } }] return yaml.dump({'resources': resources}) ``` Of course, you can do a lot more in Python than in Jinja, but basic things, such as simple parameter substitution, may be easier to implement and easier to read in Jinja than in Python. Templates provide access to multiple sets of data that can be used to parameterize or further customize configurations: * `env`: a map of key/value pairs from the environment, including pairs defined by Deployment Manager, such as `deployment`, `name`, and `type` * `properties`: a map of the key/value pairs passed in the properties section of the template invocation * `imports`: a map of import file names to file contents for all imports originally specified for the configuration In Jinja, these variables are available in the global scope. In Python, they are available as properties of the `context` object passed into the `GenerateConfig` method. ### Template schemas A template can optionally be accompanied by a schema that describes it in more detail, including: * `info`: more information about the template, including long description and title * `imports`: any files imported by this template (may be relative paths or URLs) * `required`: properties that must have values when the template is expanded * `properties`: A `JSON Schema` description of each property the template accepts Here's an example of a template schema: ``` info: title: The Example description: A template being used as an example to illustrate concepts. imports: - path: helper.py required: - prop1 properties: prop1: description: The first property type: string default: prop-value ``` When a schema is provided for a template, DM uses it to validate properties passed to the template by its invocation, and to provide default values for properties that were not given values. Schemas must be supplied to DM along with the templates they describe. ### Supplying templates Templates can be supplied to DM in two different ways: * They can be passed to DM along with configurations that import them, or * They can be retrieved by DM from public HTTP endpoints for configurations that reference them. #### Template imports Configurations can import templates using path declarations. For example: ``` imports: - path: example.py resources: - name: example type: example.py properties: prop1: prop-value ``` The `imports` list is not understood by the Deployment Manager service. It's a directive used by client-side tools to specify what additional files should be included when passing the configuration to the API. If you are calling the Deployment Manager service directly, you must embed the imported templates in the configuration passed to the API. #### Template references Configurations can also reference templates using URLs for public HTTP endpoints. DM will attempt to resolve template references during expansion. For example: ``` resources: - name: my-template type: https://raw.githubusercontent.com/my-template/my-template.py properties: prop1: prop-value ``` When resolving template references, DM assumes that templates are stored in directories, which may also contain schemas, examples and other supporting files. It therefore processes template references as follows: 1. Attempt to fetch the template, and treat it as an import. 1. Attempt to fetch the schema for the template from `/