by Indrek Ots

• articles

Tags

• sugarcrm
• vcs
• version control
• deployment
• configuration management
• ansible
• php
• vagrant

Notice! This post is more than a year old. It may be outdated.

SugarCRM is a web based customer relationship management system written in PHP. I’m fairly new to this piece of software and I started to figure out how to manage changes and multiple environments of SugarCRM. My plan was to have my own local development environment, a staging and a production environment.

Problems with SugarCRM

In SugarCRM, users are allowed to define their own custom modules. These are essentially new tables in the database. They can define data types and add constraints to new fields. In addition to changes in the database, SugarCRM generates new PHP files as well. In order to keep 2 environments in sync, both file system level changes and database changes need to be transferred. While being very flexible towards its users, SugarCRM is at first glance difficult to handle by operations.

I’m going to rephrase the problem a bit more clearly. Users are able to basically create new database tables and generate new PHP files without them knowing what is happening in the background. If I create a new module in my local environment, I need to have this module be present in the staging environment for testing as well. This means the new PHP files and database changes need to be applied to the staging environment. Without knowing much about SugarCRM, this seems to be an easy task. Source code changes can be handled by version control and database changes could be handled by some kind of database migration tool (e.g. Flyway). But as usual, life is not as easy as it seems.

Handling source code changes - version control

When it comes to source code changes, yes, version control is the way to go. But there are some things to keep in mind. You should not add all SugarCRM’s files to source control or you’ll end up in merge conflict hell. As far as I understand, Sugar does some magic and generates new source files in the /cache directory which is used during runtime. So that folder can be excluded from version control. But there are others as well.

I’m using Git for version control. The following is my .gitignore file which instructs Git from not adding the specified files and folders to version control. As you can see, a lot of files can be ignored.

Handling changes in the database

Handling database changes is more difficult. You need to know which database tables are changed and which ones need to be kept in sync. Sugar does not generate migration files. After doing some testing and googling, I came to a conclusion that at first, I should track the changes in the fields_meta_data table. When you create a new custom module and deploy it, SugarCRM creates a new database table for it. Additionally, it is able to recreate that table from the generated PHP files. But when you decide to edit a deployed module, the changes are added to the fields_meta_data table.

In addition to fields_meta_data table, I’m interested in the workflow related tables as well. Since some workflow information is stored in the database, I need them to be available in other environments too.

I created a database folder in the root of the SugarCRM folder and I’m going to add database dumps there. To make sure I’m not going to forget to take a database dump before a commit, I created a git pre-commit hook which does it for me.

Automate the creation of a new environment

Before even starting to investigate how to manage multiple environments of Sugar, I decided to first automate the creation of a clean environment. I reckoned I was going to mess up the installation at some point. So having a quick and easy way to recreate the environment was a must for me. There are many configuration management tools out there that can do the job. I decided to use Ansible for provisioning since I’m most familiar with it. But you can achieve the same results with Chef, Puppet or Salt. In addition, I’m using Vagrant to create a new virtual machine. Later I am able to use Ansible for deployments.