Skip to content

Reusable Recipes : LAMP example

Vincent Zurczak edited this page Mar 26, 2015 · 2 revisions

Reusable Recipes

Associated Discussion: 264

Status: Draft (2015-03-25)

Editors:

Revisions


WARNING:
This specification is a DRAFT: a work in progress that is intended to be
published, which may or may not be ready for adoption. It should not
necessarily be considered factual or authoritative.

Introduction

If the main guidelines have been discussed, some adjustments need to be done about how to write and use shared recipes. This page provides an example based on Roboconf's Hello World, the LAMP use case, from a realistic angle.

First Option: independent recipes

Reusable recipes

We assume the following recipes have been shared.

Apache as a load balancer

Apache-mjk-latest {
	installer: puppet;
	imports: loadbalance_able_ajp.*;
	exports: ip;
}

facet loadbalance_able_ajp {
    exports: ip, portAJP = 8009;
}

Tomcat

Tomcat-latest {
	installer: puppet;
	exports: ip, port = 8080;
}

MySQL

MySQL-latest {
	installer: puppet;
	exports: ip, port = 3306;
}

Custom Application

We now want to build a custom application that reuse the previous recipes.
Here is a graph.

import /something.mysql/main.graph;
import /something.apache/main.graph;
import /something.tomcat/main.graph;

My-web-app {
	installer: bash;
	imports: MySQL.*;
}

Tomcat {
	# Link Tomcat with apache
	extends: Tomcat-latest;
	facets: loadbalance_able_ajp;

	# Make the glue between my web application and Tomcat
	children: My-web-app;
}

Let's take a look about another option.

Second Option: linked recipes

Reusable recipes

We assume the following recipes have been shared.

Apache as a load balancer

Apache-mjk-latest {
    installer: puppet;
    imports: loadbalance_able_ajp.*;
    exports: ip;
}

facet loadbalance_able_ajp {
    exports: ip, portAJP = 8009;
}

Tomcat

import /something.apache-mjk-latest/main.graph;

Tomcat-latest {
	installer: puppet;
	exports: ip, port = 8080;
	facets: loadbalance_able_ajp;
}

MySQL

MySQL-latest {
	installer: puppet;
	exports: ip, port = 3306;
}

Custom Application

We now want to build a custom application that reuse the previous recipes.
Here is a graph.

import /something.mysql/main.graph;
import /something.tomcat/main.graph;

My-web-app {
	installer: bash;
	imports: MySQL.*;
}

Tomcat {
	# Make the glue between my web application and Tomcat
	extends: Tomcat-latest;
	children: My-web-app;
}

This solutiopn has one advantage: the loadbalance_able_ajp.portAJP variable can be injected in Tomcat's recipe. It means it does not have to be the default port. It could be changed through Roboconf files. But, it has one drawback. There is a dependency between Tomcat and Apache. And if someone wants a Tomcat, he/she will have an Apache in its graph, no matter if it is used or not.

Reusable recipes should draw the minimum set of dependencies, and even none.**

We could configure the portAJP of the Tomcat in the first option by simply defining a variable for portAJP in the recipe. As an example, assuming we use Puppet...

module ... ( ..., $portAJP = 8009 ) 

If we use Tomcat without Apache, we have the default value injected in the configuration files. And if we plug Tomcat with Apache, like we did in the first option, graph modified values will be propagated in the configuration files.

There are very few interactions between configurations. Apache - Tomcat is one of these cases where we can foresee such a tight link.

Let's take a look about another option.

Third Option: Tomcat forces its children

Reusable recipes

We assume the following recipes have been shared.

Apache as a load balancer

Apache-mjk-latest {
	installer: puppet;
	imports: loadbalance_able_ajp.*;
	exports: ip;
}

facet loadbalance_able_ajp {
    exports: ip, portAJP = 8009;
}

Tomcat

# Tomcat's recipe anticipated the possibility of configuring the portAJP.
Tomcat-latest {
	installer: puppet;
	exports: ip, port = 8080;
	children: Tomcat-web-app;
}

facet Tomcat-web-app {
	# nothing
}

MySQL

MySQL-latest {
	installer: puppet;
	exports: ip, port = 3306;
}

Custom Application

We now want to build a custom application that reuse the previous recipes.
Here is a graph.

import /something.mysql/main.graph;
import /something.apache/main.graph;
import /something.tomcat/main.graph;

My-web-app {
	installer: bash;
	facets: Tomcat-web-app;
	imports: MySQL.*;
}

Tomcat {
	# Link Tomcat with apache
	extends: Tomcat-latest;
	facets: loadbalance_able_ajp;
}

I do not know what is the best option with respect to the first option.
By having the Tomcat component as minimal as possible, I think we give more flexibility to reuse it. But this is a single point of view. Like very often, we may have several recipes that install the same Software.