Login | Register
My pages Projects Community openCollabNet

autoinst
Wiki: ExampleUsage

Edit this page | Links to this page | Page information | Attachments | Refresh page

 

Autoinst Example Usage

This document assumes you've already installed, configured, and setup Autoinst. See the InstallationGuide and ExampleSetup documents if you need assistance with these steps.

Example Application

Let's say we have a Apache+PHP application (let's say we're setting up OpenX webservers) that we want to configure using Autoinst. First, let's see what we have in our example environment.

Servers - we have two production webservers in the east coast and two in the west coast, we also have a QA machine.

  • web1.east.example.com
  • web2.east.example.com
  • web1.west.example.com
  • web2.east.example.com
  • web1.qa.example.com

Creating Hosts

First off, for each of our hosts, we want to create a version controlled entry in Autoinst representing properties for that host.

$ ai create -o web1.east.example.com
$ ai create -o web2.east.example.com
$ ai create -o web1.west.example.com
$ ai create -o web2.west.example.com
$ ai create -o web1.qa.example.com

Since we don't yet have any custom properties, the default host entry will suffice.

Creating Groups

Now, we want to organize these hosts into a group. Autoinst groups are containers that can group together hosts. So we create the following groups:

$ ai create -g datacenter.east
$ ai create -g datacenter.west
$ ai create -g datacenter.qa

So, we've just created three groups -- one group represents our east coast servers, one represents our west coast servers, and one group represents our QA servers.

So far, so good. Except our groups don't have any hosts in them! So let's add hosts to the groups.

$ ai edit -g openx.east

<?xml version="1.0" encoding="UTF-8"?>

<group version="3.0.0" name="datacenter.east">
  <hosts>
   <host name="web1.east.example.com"/>
   <host name="web2.east.example.com"/>
  </hosts>

  <groups/>

  <profiles/>

  <!-- properties specific to this group -->
  <properties/>
</group>

What this just did was add 'web1.east.example.com' and 'web2.east.example.com' to the 'datacenter.east' group. Repeat this for the 'datacenter.west' and 'datacenter.qa' groups.

Creating Profiles

Profiles represent a basket of actions that should be applied to a host. An action represents a single configuration file. So a profile can be used to manage a set of configuration files that should be applied to a host.

In our example, we only need one profile, since it will represent all the configuration files on our hosts:

$ ai create -p openx.web

Linking Profiles to Groups

Now that we have a profile created, we want to link it to our new groups. What this means is that all three of the groups now have the 'openx' profile as a set of configuration files to manage.

$ ai edit -g datacenter.west

<?xml version="1.0" encoding="UTF-8"?>

<group version="3.0.0" name="datacenter.west">
  <hosts>
   <host name="web1.west.example.com"/>
   <host name="web2.west.example.com"/>
  </hosts>

  <groups/>

  <profiles>
   <profile name="openx.web"/>
  </profiles>

  <!-- properties specific to this group -->
  <properties/>
</group>

But what does this accomplish? Nothing yet, because all three groups have the same profile, although they do have a different set of hosts.

Creating Actions

Actions are configuration templates. You can think of each action as being a one-to-one mapping to a single configuration file on the system.

Let's say we want to manage the file '/var/www/html/openx/var/db.conf' using autoinst. This file gets included by other static configuration files, but the file needs to be different depending on the datacenter (because each datacenter uses a different database server).

$ ai create -a openx.web.db.conf

<?xml version="1.0" encoding="UTF-8"?>

<action version="3.0.0" name="openx.web.db.conf" 
        filename="/var/www/html/openx/var/db.conf"
        user="apache" group="apache" mode="0644"
        stylesheet="default.xsl" method="text" encoding="UTF-8">

  <properties>
    <property name="openx.db.host">localhost</property>
  </properties>

<template>

[database]
type=mysql
host=<property name="openx.db.host"/>
socket=
port=3306
username=openx
password=abc123
name=openx
persistent=
mysql4_compatibility=1
protocol=tcp

</template>

</action>

What does this accomplish? This creates a configuration template that manages /var/www/html/openx/var/db.conf, and it has a placeholder for the 'host' entry called 'openx.db.host'. However, the default is 'localhost', which isn't going to work for us in production. We'll fix that in a minute.

Linking Actions to Profiles

Now that we've created the action, we need to link it to our profile.

$ ai edit -p openx.web

<?xml version="1.0" encoding="UTF-8"?>

<profile version="3.0.0" name="openx.web">

  <!-- the actions that are associated with this profile -->
  <actions>
   <action name="openx.web.db.conf"/>
  </actions>

  <properties/>
</profile>

Checkpoint

What have we accomplished so far?

  • Created host entries for all our servers.
  • Created a group entry for west, east, and QA.
  • Created a profile called 'openx.web' which represents all of our OpenX webservers.
  • Created an action template that manages the db.conf file on all our machines.
  • Linked everything together - group to hosts, group to profiles, and profile to action.

Setting Properties

Properties are one of the things that make Autoinst useful for managing configuration files. In our example, we want to set a different DB hostname depending on what datacenter our server is in. Well, it just happens that we've created an Autoinst group for each of our datacenters!

So how do we set this up? By setting group properties:

$ ai edit -g datacenter.east

<?xml version="1.0" encoding="UTF-8"?>

<group version="3.0.0" name="datacenter.east">
  <hosts>
   <host name="web1.east.example.com"/>
   <host name="web2.east.example.com"/>
  </hosts>

  <groups/>

  <profiles>
   <profile name="openx.web"/>
  </profiles>

  <!-- properties specific to this group -->
  <properties>
   <property name="openx.db.host">db1.east.example.com</property>
  </properties>
</group>

But we set things up differently in the 'datacenter.west' group:

$ ai edit -g datacenter.west

<?xml version="1.0" encoding="UTF-8"?>

<group version="3.0.0" name="datacenter.west">
  <hosts>
   <host name="web1.west.example.com"/>
   <host name="web2.west.example.com"/>
  </hosts>

  <groups/>

  <profiles>
   <profile name="openx.web"/>
  </profiles>

  <!-- properties specific to this group -->
  <properties>
   <property name="openx.db.host">db1.west.example.com</property>
  </properties>
</group>

What does this all mean? What we've done is configured group-specific properties for each group. When we finally get to the point where we generate configuration files, the template will be populated with the property for that group depending on the context of group membership. In other words, we want the servers in the 'datacenter.west' group to connect to 'db1.west.example.com', and the server in the 'datacenter.east' group to connect to 'db1.east.example.com'. Our templates and group properties let us do this by writing a single template, and then configuring group-specific properties.

Other Properties

Besides group-level properties, profiles and hosts can have properties. Why might you need to use this?

  • If you have multiple profiles re-using the same action template, they might have different default settings.
  • If you want to test out something on a single host, you might want to override a setting at the host level.
  • Any other reason you might want to be flexible.

Properties are merged in the following order:

  • Action properties are overridden by profile properties
  • Profile properties are overridden by group properties
  • Group properties are overridden by host properties

This lets you go from the least specific (template defaults) to the most specific (host-level settings)

However, the bulk of properties will (and should) be at the group level, because the group represents a container of "hosts that should be configured in the same way".

Testing the Configuration

Now that we've got our configuration framework setup, let's test it out:

$ ai run -g datacenter.west -p openx.web -a openx.web.db.conf

[database]
type=mysql
host=db1.west.example.com
socket=
port=3306
username=openx
password=abc123
name=openx
persistent=
mysql4_compatibility=1
protocol=tcp

'ai run' let's us see what the final configuration file will look like for a given group. We feed it the group name, profile name, and action name, and it returns the merged configuration file, basically what belongs on all the hosts in this group. If we specified a host (and had host-specific properties), then the configuration file for that host would be shown in the output.

For example:

$ ai run -o web1.west.example.com -g datacenter.west -p openx.web -a openx.web.db.conf

[database]
type=mysql
host=db1.west.example.com
socket=
port=3306
username=openx
password=abc123
name=openx
persistent=
mysql4_compatibility=1
protocol=tcp

Except this returns the same thing, because we don't have any host-specific properties.

Managing Hosts using 'aiupdate'

Autoinst comes with a tool called 'aiupdate' that lets you manage Autoinst-managed configurations on a host. It's completely optional for you to use. 'aiupdate' has very few prerequisites and should work with most stock installations of Python 2.x without any additional modules or extensions.

If we login to one of our hosts, let's say 'web1.east.example.com', we can run this command:

$ aiupdate

Actions to install for web1.east.example.com:
=============================================================================
 Action                  Group                Profile
=============================================================================
 openx.web.db.conf       datacenter.east      openx.web

Confirm [y/N]: y

If we look in /var/www/html/openx/var/db.conf, we should see our configuration file, substituted with the settings specific to our host, group, and profile.

If gethostname() is not reliable on your system, you can feed options to aiupdate, e.g. 'aiupdate -H web1.east.example.com' will force the hostname to be 'web1.east.example.com'.

You can also feed 'aiupdate' options to be silent and answer 'yes' to all questions, if you wanted to run it from 'cron'.

If you use another mechanism to manage hosts (e.g. cfengine, Puppet, or slack), then you can simply run 'ai run' to generate files (as shown in the previous section), and use Autoinst as a way to version control configuration files, and then your other tool as a distribution mechanism.

Tagging the Configuration

Because everything is managed in version control, it is straightforward for us to use tags to manage our deployments. This is useful, because we can always recreate our configuration environment at any time, for any version.

Let's say we wanted to create a tag to represent a deployment tomorrow, and we'll arbitrarily call the tag 'LAUNCH-21' since this is our 21st launch.

$ ai tag LAUNCH-21
Enter username for Autoinst at localhost: admin
Enter password for admin in Autoinst at localhost: 
OK

This creates a SVN tag of the repository named 'TEST1'.

Now we can do a configuration deployment from this tag. If someone makes a change to the trunk, it doesn't matter, since we are deploying from a tag. For example:

$ aiupdate -t LAUNCH-21

or

$ ai run -o web1.west.example.com -g datacenter.west -p openx.web -a openx.web.db.conf -t LAUNCH-21

This would update everything on the host from tag LAUNCH-21. Everyone else can continue working on trunk, but production will update from this tag.

Branching the Configuration

Autoinst also support branches. Let's say you wanted to work on some configuration changes on a branch, but didn't want to disrupt the rest of the team's work on the trunk.

$ ai branch MY_TEST_BRANCH

This would create a new branch. If you want to make changes to it, simply specify the branch name in the tools:

$ ai edit -g datacenter.west -b MY_TEST_BRANCH

This would edit the 'datacenter.west' group on the MY_TEST_BRANCH.

You can test out changes on the branch, for example:

$ ai run -o web1.west.example.com -g datacenter.west -p openx.web -a openx.web.db.conf -b LAUNCH-21

When you're done, you can copy and paste the changes into the trunk, or even create a tag. A merge command is not supported at this time, only copy-paste hand merges.

When you're done, you can delete the branch:

$ ai remove -b MY_TEST_BRANCH

ExampleUsage (last edited 2009-02-24 00:51:26 -0700 by ?mlum)