In "Infrastructure as Code: From the Iron Age to the Cloud Age," Kief Morris describes the Iron Age as a time when "infrastructure growth was limited by the hardware purchasing cycle. Since it could take weeks for a new server to arrive, there was little pressure to rapidly install and configure an operating system on it."
But now, in the Cloud Age, systems are deployed using cloud services. Many of these services, including Contentful, provide friendly user interfaces (UI) where users can configure environments. Unfortunately, as the number of services that teams operate grows, it becomes unmanageable to maintain each one by pointing and clicking through the UI. "Infrastructure as code" is an approach to deal with this issue: The configuration of each service is automated, and that configuration is stored along with the source code for the application in version control.
Monolithic CMS platforms commonly used today don't work well for teams that employ agile development practices, such as infrastructure as code and continuous delivery. Provisioning, migrating and testing those platforms is inherently difficult to automate.
Contentful, on the other hand, is content infrastructure built for the Cloud Age.
In the Iron Age, software development was built around the idea of boxed software—with new versions released once a year, or even less. Expensive and time-consuming release processes were common, with the status quo being build everything, test everything, and then release everything.
In the Cloud Age, agile teams release frequently, often several times a week, so expensive and time-consuming release processes can’t be used without grinding deployments to a halt. For this reason, many agile teams have adopted continuous delivery.
Teams that employ continuous delivery have a deployment pipeline, a set of validations through which new version of software must pass on its way to production. The pipeline has different stages, each of which has its own environment for running the software.
Here are what the steps in the deployment pipeline look like:
Teams using Contentful can provision environments, migrate content and write tests using APIs, allowing content management to fit into agile development practices, enabling software development teams to create high-quality software and to deploy quickly.
While adopting continuous delivery might require some upfront investment and change in team culture, the long-term business benefits outweigh any associated pains:
For the software to run in each environment, it requires not only the source code for the software but also infrastructure, such as the services and attached resources that it depends on. A common example is a database. If the software requires a database to be available, then one will need to be provisioned for each environment.
Many teams developing software that depend on databases are familiar with this situation. They have Dev, QA and Production databases set up with provisioning and migration scripts. These scripts can create databases for the correct schema for the current version of the software, updating it from a previous version to the current one. The scripts can also update actual data, when the data model changes in such a way that existing data is no longer valid according to the new schema. Finally, the team will also create integration tests that validate that the database, schema, and sometimes data are correct for the current version of the software.
This is also true for SaaS: if the software makes use of a SaaS, then this service needed to be available and configured for the given environment. SaaS is infrastructure, and to work with continuous delivery, SaaS needs to be treated as code.
Contentful allows teams to create Spaces, which are like databases for Content. As with the databases example above, teams will often have developer, QA, and production spaces set up in Contentful.
A further challenge for content management is that there are two lifecycles happening at the same time, both requiring authoring, verification, and release: one is the software deployment pipeline, the other is the content creation workflow. While software developers are authoring and releasing software versions, content creators are at the same time authoring and releasing content.
Contentful comes with a built-in workflow that supports draft and published stages that control when content is available to your live systems. Our platform also has a preview API that can be used for content review, as well as features to build your own, more advanced workflows. Content creation happens using just one production space: content creators create drafts, which are reviewed by way of the preview API, and then published. The other spaces are only used as part of the software deployment pipeline.
Furthermore, Contentful provides a CMS as a service which can be treated as code and included in your deployment pipeline. To accomplish this, you need to have provisioning scripts and migration scripts.
Provisioning scripts can configure a space with your content model, while migration scripts migrate a space from an older content model to the current one. When needed, migration scripts modify entries so that they are valid according to the current model. Teams should also write tests that can be run to verify that the current software works with the current content model and latest content.
Implementing CMS as Code requires saving the content model in your version control repository along with the rest of your source code, so that the version of the software revision matches the version of the content model. This is done by using the Export tool, to request the configuration of all Content Types that have been added to the Dev Space and saving them.
When new spaces are created, it is useful to have some content to work with. Teams can save enough content to run and test the software by using Contentful's Import and Export tools. They can save the content in version control as JSON files, and then load this content into the newly created spaces using provisioning scripts.
Databases and platforms such as Ruby on Rails have well-developed migration strategies. For CMS as code, the migration scripts need to be written by the team. Contentful’s migration-cli, can help in the creation of such scripts.
Traditional “Rails style” migrations have
down functions for each version of their saved content models. The
up function should be able to migrate a space to the latest version from the previous one, while the
down function, should do the reverse.
Real-world experience shows that while teams spend many hours maintaining
down functions, they frequently run into problems when they try to use them. There is often no real way to
down migrate content without resorting to backups. For instance, old content may have been dropped, or relationships that were formerly one-to-one, may now be one-to-many, meaning that reverting would lose content. A forward-only plan, along with good backups, is generally a better option.
A forward-only migration plan should use an expand and contract pattern to safely make backward incompatible changes to your content model, instead of writing down functions.
The expand phase should add new fields and content types, and transform content entries such that the changes do not prevent the currently released version of the software from running. By leaving the existing content in place, while augmenting the content types and content such the new version of the software can also run. The content model can now support both the current version and the new version of your software in parallel. Your software can now be released to your QA users, and rolled out to the rest of your user base. If a problem occurs at any point, the rollout can be stopped and reverted.
Once all users are successfully using your new version, the contract phase of the migration is run to remove unneeded content types, fields, and content.
To illustrate this process with a simple example, consider a blog system that only has one content type, a
Post content type has an
Author field in it, which is a text field where editors can enter the author’s name. In the next release of the software, new requirements result in the need for
Author to be an independent content type that is referenced from
The expand phase does not alter the
Author field or its content. Rather, it adds a new field called, for example,
The migration would iterate through each
Post entry, and create a new
Author entry for each of the old
Author fields, and set
AuthorRef as a reference to this new
Your editorial teams can now add additional information to the
Author entries, while the existing software continues to run, as it depends only on the old
When the content is ready, you can begin to roll out your new software. If problems occur at any point, you can revert the rollout.
Once the rollout has successfully completed, your contract phase can now run and remove the old
Author field permanently. If you prefer to use the name of the old field instead of the name used in the expand phase, you can do this as a separate migration, with its own expand and contract phases. If you can just use the new name, then your migration is complete.
In case you need to revert, it's a good idea to have a backup to recover from. In any case, you can create a new forward migration to return to the old content model.