Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Add an Application Model object #148

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 207 additions & 0 deletions 4.application_model.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
# Application Model

The Hydra approach identifies four important roles:

- The developer: Creates and maintains components (microservices)
- The application architect: Defines an application as composed of components
Copy link
Member

@resouer resouer Sep 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The architect role makes sense, though we already have roles-and-responsibilities section, we may want to consider aligning them together?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I will fit the ideas in this document into the other sections.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of the customer feedback I received last week was that developers shouldn't be concerned with component creation or maintenance. In the customers' opinion, workload type and resource consumption should be an application architect concern, and developer involvement should drop off @ CI/CD.

I'm not saying we necessarily have to nix the developer from the personas, but it's something to consider in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, and this is why components can be specified inline (by app architects) for those orgs. But I got other feedback saying the app developers ought to be able to have complete control over their component configurations, so they needed the option to have separate files.

To solve this conundrum, I made it so that the components section could either define the components inline (e.g. the "strong app architect" model) or provide a reference to component specs created by developers (the "strong developer" model).

- The application operator: Instantiates an application, providing configuration
- The infrastructure operator: Maintains the underlying platform, making low-level decisions about infrastructure

The previous section of the specification defines the component model. This section defines how components can be composed in an application.

> The term "application" is not intended to provide a one-size-fits-all definition of what an application is. Rather, it is used to describe how a set of related components can be treated as a single functional unit. Our use of the term is not intended to enforce a particular design methodology. Users of the Hydra platform may, for example, use several application models to describe a single large platform.

## Representation

The `ApplicationModel` object follows the same basic structure as other Hydra manifests.

### Top-Level Attributes

The top-level attributes of a trait define its metadata, version, kind, and spec.

| Attribute | Type | Required | Default Value | Description |
|-----------|------|----------|---------------|-------------|
| `apiVersion` | `string` | Y || The specific version of the specification in use. At present only `core.hydra.io/v1alpha1` is defined. |
| `kind` | `string` | Y || The string `ApplicationModel` |
| `metadata` | [`Metadata`](#metadata) | Y | | ApplicationModel metadata. |
| `spec`| [`Spec`](#spec) | Y || A specification for application models. |

### Metadata

Metadata describes this Application Model. The metadata section is defined in [Section 3](3.component_model.md#metadata).

### Spec

The job of an Application Model is to relate multiple components to a single functional unit. The `spec` section declares the relationship.

| Attribute | Type | Required | Default Value | Description |
|-----------|------|----------|---------------|-------------|
| components | [][ComponentReference](#componentreference) | y | | The list of components in this Application Model |

### ComponentReference

| Attribute | Type | Required | Default Value | Description |
|-----------|------|----------|---------------|-------------|
| metadata | [Metadata](#metadata) | n | | The metadata for a component |
| spec | [ComponentSpec](3.component_model.md#spec) | n | | A component schematic |
| reference | string | n | | The name of an external component |

*IMPORTANT:* If `reference` is not provided, both `spec` and `metadata` are required. If `spec` is provided, `reference` MUST be ignored and MAY produce an error if present.

The following example shows two components, one inline schematic, and another external reference:

```yaml
components: # This is a list of the components that make up this app.
- metadata:
name: admin-portal
annotations:
version: "1.0.0"
description: Administration portal
spec:
workloadType: core.hydra.io/v1alpha1.ReplicatedService
containers:
- name: server
image: example/admin:v1.2.3
- reference: my-database
```

## Example Application Model

This example shows a three-component application model, where all three components are declared inline.

```yaml
apiVersion: core.hydra.io/v1alpha1
kind: ApplicationModel
metadata:
name: example-app-model
annotations:
version: v1.0.0
description: >
An example app model that is composed of three components
icon: https://example.com/assets/example/icon.png
spec:
components: # This is a list of the components that make up this app.
- metadata:
name: admin-portal
annotations:
version: "1.0.0"
description: Administration portal
spec:
workloadType: core.hydra.io/v1alpha1.ReplicatedService
containers:
- name: server
ports:
- containerPort: 5001
name: http
image: example/admin:v1.2.3
- metadata:
name: database
annotations:
version: "1.0.0"
description: PostgreSQL Database
spec:
workloadType: core.hydra.io/v1alpha1.Singleton
containers:
- name: db
ports:
- containerPort: 5432
name: pgsql
image: example/postgres:9.4
- metadata:
name: frontend
annotations:
version: "1.0.0"
description: Front-end webserver
spec:
workloadType: core.hydra.io/v1alpha1.ReplicatedService
parameters:
- name: username
description: Basic auth username for accessing the administrative interface
type: string
required: true
- name: password
description: Basic auth password for accessing the administrative interface
type: string
required: true
- name: db-host
description: Host name or IP of the backend
type: string
required: true
containers:
- name: server
ports:
- containerPort: 5000
name: http
image: example/front-end:v1.2.3
```

In some cases, it is beneficial to declare the components separately (as defined in Part 3), and then merely reference them from an Application Model:

```yaml
apiVersion: core.hydra.io/v1alpha1
kind: ApplicationModel
metadata:
name: example-app-model
annotations:
version: v1.0.0
description: >
An example app model that is composed of three components
spec:
components: # This is a list of the components that make up this app.
- reference: admin-portal
- reference: database
- reference: voting-frontend
```

Of course, an Application Model may freely mix references to components and inline components.

### Limits on Inline Components

When a component is declared _inline_, it is considered _application specific_, and is not made available in the general catalog of components. Conversely, applications that are defined in stand-alone `ComponentSchematic` definitions are made available in the general catalog of components, and may be referenced from any number of `ApplicationModel` definitions.

## Referencing Application Models from Application Configurations

An application model declares _the parts of an application_. An Application Configuration provides _configuration for a particular instance of an application model_. For example, an Application Model may define the parts of a blog platform, while an application configuration defines a particular instance of that blog platform. One model may be instantiated numerous times, with each instance having its own configuration.

```yaml
apiVersion: core.hydra.io/v1alpha1
kind: ApplicationConfiguration
metadata:
name: custom-single-app
annotations:
version: v1.0.0
description: "Customized version of single-app"
spec:
# Specify which Application Model is to be instantiated
applicationModel: example-app-model
# Provide configuration specific to the defined components:
components:
- componentName: frontend
instanceName: web-front-end
parameterValues:
- name: db-host
value: my-db.cluster
- name: user
value: db-user
traits:
- name: app-ingress
type: core.hydra.io/v1alpha1.Ingress
properties:
- name: host
fromParam: domainName
- name: path
value: "/"
# For these, we are just declaring the instance names, not setting params or
# traits.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? Aren't parameters and traits required to instantiate the database and admin-portal components, both of which are necessary in order for the application to run successfully since they're part of the same application model as the front-end component?

- componentName: database
instanceName: my-db
# This is the default behavior:
# - componentName: admin-portal
# instanceName: admin-portal
```

In the example above, the Application Configuration declares that it is an instance of `applicationModel: example-app-model` (which was defined earlier in this section). It provides instance-specific settings, like the names, parameter values, scopes, and traits that are to be applied to this application instance.

## Considerations

The ApplicationModel's components declare parameters, but there is currently no facility for declaring a "top level" parameter that would bubble down to individual components. The reason for this omission is that referenced components are assumed to have no knowledge of the Application Model(s) in which they are referenced. Thus, they cannot reference the values defined in an Application Model.