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 UIs 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: configuration of each service is automated, and the 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 a CMS 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 build everything, then test everything and then release everything being the way it was done.
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 have their own environments where the software can run.
Teams using Contentful can provision environments, migrate content and write tests using APIs, allowing content management to fit into agile development practices such as Infrastructure as Code and Continuous Delivery, 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 needs 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 Dev, 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 provides a basic workflow built-in, with draft and published stages that control when content is available to your live systems, 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.
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, which can configure a space with your content model, and migration scripts, which can migrate a space from an older content model to the current one and, when needed, 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 Contentful's Management API to request the configuration of all Content Types that have been added to the Dev
Space and saving them, usually in JSON files.
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 Management API. They can save the content in version control as JSON files, and then load this content into the newly created spaces by means of 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. Tools like Node-Migrate, can help in the creation of such scripts, as they provide basic platform agnostic migration functions.
A migration script should have an up
and a down
function for each version of your saved content model. 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.
To illustrate this process with a simple example, consider a blog system that only has one content type, a Post
. The 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 Post
.
Before loading the new content model into the space, the up
function of the migration would export all Post
entries and save them locally; it would then load the new model, iterate through each Post
entry, and create a new Author
entry for each of the old Author
fields.
The down
function would do the reverse: export and then delete all Author
entries, reload the old content model, iterate through the saved content, and populate all Post.Author
fields with the value of the name from the saved Author
entries.
Contentful provides a set of composable tools, Contentful-Export and Contentful-Import, to make writing provisioning and migration scripts easy. These tools allow you to work with the data in a space as a single JSON document, allowing you to implement the transformation it needs according to the business requirements.