CMS as Code

Contentful's content infrastructure makes it possible to treat your content as code

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.

Table of contents

Continuous delivery

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.

Editing-Diagram Waterfall Contrast

Here are what the steps in the deployment pipeline look like:

  1. Development: This often happens on developers' personal computers, where they author new versions of the software. When developers want to deploy a new version, they commit their latest code to a version control system and push it to a shared repository. This initiates the pipeline.
  2. Build: This depends on a build script that is capable of creating the running version of the software from the source code, performing steps like installing dependencies, compiling, or transpiling code and verifying that the build script runs successfully.
  3. Test: This relies on automated tests being available to verify that the software works as expected and that new versions have not broken functionality that worked in previous versions.
  4. QA: Developers and QAs use the software and perform more testing, ensuring that the acceptance criteria for the most recent changes have been met and the software is ready for production.
  5. Deploy: The software is uploaded to production servers. The new version is now live.

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:

  • Faster time to market: Continuous delivery facilitates and encourages shorter delivery cycles.
  • Improved engineering practices: When the business demands more regular release cycles, technology teams are incentivized to leverage higher levels of automation and to adopt practices such as test-driven development.
  • Reduced risk: By having small and more focused deployments, it is less likely to have something go wrong than in bigger and more complex releases.
  • Releasing is a business decision: Taking away the complexities of deployment from developers also means that the release of a new feature can happen independently from them, leaving business stakeholders in charge of pushing the button.
  • Exposed inefficiencies: A continuous delivery system can shift focus from the development inefficiencies to the real problems that are causing them—for instance, unclear requirements.

Infrastructure as code

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.

Pipelines and workflows

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.

Editing-Diagram AuthoringEditing Contrast

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.

How to get started

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 up and 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.

Editing-Diagram-transition Contrast

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.

The expand phase does not alter the Author field or its content. Rather, it adds a new field called, for example, AuthorRef.

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 Author Entry.

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 Author field.

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.

Contentful has import, export and migration tools that can be used to make the provisioning and migration scripts easy, allowing agile teams to treat your CMS as code.

Discover Contentful

Learn how Contentful works

Read about our content management infrastructure, our flexible APIs and our global CDN.
View key features

See how our customers use Contentful

From apps and sites to digital signage and iBeacon campaigns — we deliver content everywhere.
Explore other customers