Updated March 24, 2023
11 min read

Environment as a Service (EaaS): Benefits and Best Practices

Discover how environment as a service (EaaS) technology can enhance developer productivity, reduce costs, and improve product quality.

Environment as a service (EaaS) describes a method of provisioning full hosted application environments, including the application code, dependencies, runtime binaries, and configuration files. Development teams use EaaS to rapidly create ephemeral environments for individual feature branches that mimic their production environments. Developers use such ephemeral environments to test software under realistic conditions and remove the environments after testing.

Git strategy for ephemeral preview environments
Figure 1: EaaS creates an ephemeral preview environment for every Git branch.

This article covers the features and benefits of EaaS, explains its use cases, and offers tips and recommendations for adopting it. It concludes with a discussion of best practices, including a series of instructions, code snippets, and examples to help you implement EaaS effectively and obtain the best possible outcome.

Summary of environment as a service concepts

Here are the key ideas presented in this article

Concept Description
Definition of environment as a service (EaaS) EaaS is a technology that automatically provisions test environments for developers to test code quality and helps them simultaneously manage multiple ephemeral environments.
Challenges solved by EaaS Before EaaS, developers had difficulty maintaining and sharing persistent test environments, which became a bottleneck to continuous development. Maintaining demo environments is also a common challenge addressed by EaaS.
EaaS benefits Teams widely use EaaS to create automated preview environments for each feature branch and help developers focus on writing and testing code. EaaS also improves team performance by avoiding resource contention, fostering collaboration, and reducing business expenses.
Environments hosted on EaaS platforms EaaS platforms typically support software quality testing but can also be used to create staging, demo, and development environments.
EaaS must-have features EaaS platforms should be able to set up and tear down an ephemeral environment for every feature branch and integrate with leading version control platforms, container registries, and CI/CD platforms. They should also support infrastructure as code (IaC), database seeding, and secrets management.
EaaS optional features EaaS platforms should ideally be available as an extension on the Docker desktop marketplace, support single sign-on (SSO), and provide integrated logging for troubleshooting and role-based access control.
EaaS implementation best practices To adopt EaaS, containerize your code, use Git-based version control, leverage docker-compose, store sensitive information as secrets, integrate EaaS into your CI/CD workflow, seed databases, and mock third-party services.

Challenges solved by EaaS

Let us look at some common challenges faced by software teams that EaaS solves.

Cost and resource contention

Traditional test, staging, or production environments are persistent and shared by the full development and quality assurance (QA) teams. Developers and test engineers must wait their turn to test code in centralized and permanent environments, which slows development velocity and hinders innovation. These environments remain idle at night and during times when testing is not required, wasting resources and money.

EaaS solves this suboptimal usage of resources by providing an on-demand environment for every feature branch that requires testing and then removing it automatically when the code merges with the main branch.

Sandboxing

Offering sandboxes might be a complex feature for developers to implement because it typically involves problems related to scaling, load balancing, and maintaining different code versions in multiple sandboxes. With EaaS, creating sandboxes becomes as easy as creating a new branch within version control.

Online demonstrations

Product managers often use webinars or screencasts for software demonstrations as part of user acceptance testing. With EaaS, you can also easily create and share live preview environments with your audience.

Screen sharing

Developers engage in debugging activities such as pair programming and work by sharing screens. Preview environments help developers avoid screen sharing by interacting directly with an environment created for any branch relevant to their work.

EaaS benefits

There are many compelling reasons to consider using EaaS to manage your test environments.

Efficiency

You can save time, money, and effort by letting a service provision and remove on-demand test environments. Ephemeral environments avoid idle infrastructure overnight when developers sleep and during the time in a development sprint when testing is not required.

Staying focused and reducing complexity

Developers should focus on writing test cases and finding and fixing bugs, not configuring test environments. By delegating infrastructure provisioning to an EaaS provider, developers can work on their code rather than dealing with the complexities of configuring compute, storage, networking, DNS, and database resources.

Avoiding resource contention

Developers often wait in line to test their code changes in shared environments. EaaS helps developers work independently by providing a dedicated environment for every feature branch.

Accelerating collaboration

Code reviews don’t always reveal all of the design problems or software bugs. Preview environments let code reviewers experience the code in action, speeding up the quality assurance process. They also help keep the main branch clean as developers fix issues in a feature branch before merging the changes.

Allowing for confident refactoring

Large application refactoring projects are scary and often create resistance, forcing developers to patch code instead of making fundamental changes. The smooth process provided by EaaS boosts confidence to the level needed to undertake large refactoring projects by viewing and testing incremental changes throughout the project.

Environments hosted on EaaS platforms

Here are some of the most common environments hosted on EaaS platforms.

Development and testing environments

Most development teams separate their development environments from their testing environments. Ephemeral environments hosted on EaaS platforms make it easier to operate many platforms simultaneously.

Migration testing environments

It’s a best practice to test data migrations and architectural migrations in a temporary environment before implementing the changes in production. EaaS platforms can help create parallel environments with varying configurations to test code before and after a migration.

Upgrade environments

Upgrading the version of middleware components (like the message bus and databases) can require proper testing facilitated by ephemeral environments.  

Demo environments

Product management teams often demo the most recent features to customers who requested the enhancements before their general release. Ephemeral environments can help facilitate customer demos.

Innovation environments

Research and development teams can use ephemeral environments to start on a current software release’s foundation and apply changes to showcase new design ideas for management approval.

EaaS must-have features

Here are some of the core features that an effective EaaS should offer:

  • Infrastructure as code (IaC): The EaaS platform should be able to take an IaC definition, such as a Docker Compose file, and use it to provision environments.
  • Database seeding: Stateful applications are dull to view and difficult to test without any data in the user interface. An EaaS platform should support loading data from a SQL dump file or running a script during initialization to populate the database.
  • Secret management: A secret manager allows developers to securely store passwords, tokens, API keys, and other sensitive data. These secrets are removed from the code and securely injected into the environment at runtime.
  • Development workflow integration: EaaS platforms must be able to automatically create a new ephemeral environment when a pull request (PR) is submitted by developers. They must also be able to destroy it when the PR merges into the main branch.
  • CI/CD integration: An EaaS solution must integrate with existing version control platforms such as GitHub, CI/CD platforms such as GitHub Actions, and a container registry.
  • Dashboards: In large projects, dozens of features are developed simultaneously. A single pane of glass to view and manage these environments at a glance is an essential feature.

EaaS optional features

Some additional helpful features that EaaS platforms can offer include the following:

  • Plugins and extensions: Plugins and extensions that integrate directly with development tools enhance developer productivity. For example, Uffizzi offers an extension on the Docker desktop marketplace that helps developers access preview environments from within the Docker Desktop interface. If you are not familiar with this functionality, you can learn more about Docker desktop extensions here.
  • Single sign-on: SSO allows members of an organization to sign into the EaaS dashboard via their identity providers, such as Okta or Azure SSO. For example, Uffizzi supports a number of identity providers, as documented here.
  • Integrated logging: A consolidated view into the container, build, and event logs can save a great deal of troubleshooting time. You can learn more about integrated logging features on EaaS platforms here.
  • Role-based access control (RBAC): With RBAC, admins can get finer control over who gets access to which resources, which is usually required for complying with enterprise security policies.
Environments as a Service (EaaS)
Platform
Qovery
Release Hub
Uffizzi
Lightweight and Fast (All-Container Solution)
Easy Setup
(Based on Docker Compose)
Reusable Github Actions Workflow

Cost
$$$
$$$$
$
See Comparison Table
Platform
Lightweight and Fast (All-Container Solution)
Easy Setup
(Based on Docker Compose)
Reusable Github Actions Workflow
Cost
Qovery
$$$
Release Hub
$$$$
Uffizzi
$
See Comparison Table

EaaS implementation best practices

To most effectively add EaaS into your development cycle, follow these best practices.

Containerize your code

EaaS uses containerization to set up and tear down ephemeral environments quickly. Package your application code along with dependencies such as libraries, configuration files, and binaries into self-contained containers that can run on popular runtime engines like Docker, Cri-o, or containerd.

After defining your container in a configuration file, you can build container images and upload them to a registry such as DockerHub or Amazon Elastic Container Registry. By giving access, EaaS can pull these images whenever it creates an environment. Follow this documentation to get a deeper understanding of containerization and the process of storing container images in a registry.

Store your code in a Git-based version control platform

Storing code on a Git-based version control system (VCS) is a common practice, but it’s still worth mentioning, especially since VCS platforms increasingly support built-in continuous integration functionality. CI workflows use webhooks to monitor events occurring in your code repository and can trigger EaaS to set up and tear down ephemeral environments. For example, the GitHub Actions workflow offers triggers that can integrate with EaaS platforms such as Uffizzi. Here is an example of a workflow that listens for the pull_request event. It executes the workflow whenever a pull request is raised against the main branch in the repository.


name: Pull Request Workflow

on:
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Install dependencies
      run: npm install

    - name: Run tests
      run: npm test
Figure 2: GitHub Actions workflow triggered on pull requests to `main` branch.

version: '3'

services:
  db:
    image: postgres
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword
      POSTGRES_DB: mydb

  task_queue:
    image: redis

  task_worker:
    image: my_task_worker_image
    environment:
      DATABASE_URL: postgresql://myuser:mypassword@db:5432/mydb
      REDIS_URL: redis://task_queue:6379/0
    depends_on:
      - task_queue

  web:
    image: my_web_server_image
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgresql://myuser:mypassword@db:5432/mydb
      
            REDIS_URL: redis://task_queue:6379/0
    depends_on:
      - db
      - task_worker
Figure 3: Docker Compose file example that describes an application configuration

To start with Docker Compose, refer to Docker’s getting started guide.

Manage secrets safely


Secrets include passwords, keys to third-party APIs, encryption keys, database credentials, and authentication certificates. Don’t store this sensitive information in your code: Put it in a secret manager and let EaaS inject the necessary secrets into the codebase at runtime as needed.

Here is a section of a Docker Compose file that uses variable substitution to fill in secrets at runtime:


    services:
    web:
      image: my_web_server_image
      ports:
        - "8000:8000"
      environment:
        - APP_ENV=${ENVIRONMENT:-development}
        - APP_SECRET=${APP_SECRET}  
    
Figure 4: Example Docker Compose file that passes secrets to the application via environment variables. See Uffizzi Docs for details on how secrets are configured for Uffizzi Cloud.

These values can be accessed from within the server application. Here is an example:


    import os
from flask import Flask

app = Flask(__name__)

app.config['SECRET_KEY'] = os.environ.get('APP_SECRET')

@app.route('/')
def index():
    if os.environ.get("APP_ENV") == "production":
        # Handle production tasks like calling 3rd party APIs 
        return 'Hello, you are using the production environment'
    
    return f'Hello, you are using {os.environ.get("APP_ENV")} environment'

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

    
Figure 5: Example Flask server application that reads a secret from an environment variable.

Integrate EaaS into CI/CD workflows

You can configure CI workflows so that the EaaS service is triggered by Git events like pushing commits to a branch or raising pull requests. Once triggered by an event, EaaS can provision a preview environment and make the environment accessible through a URL.The most important steps involved in such a workflow are to build a container image of your application and push the image to a container registry such as GitHub container registry. EaaS should then be able to put together your docker-compose file, the images in the container registry, and secrets in the secret manager to create the environment. You can refer to this documentation to learn more about integrating Uffizzi with CI workflows.

See how Spotify packs more into every release with ephemeral environments
Read Case Study

Seed Databases

Seeding databases with initial data makes preview environments more comprehensive and easier to test. Pick a data loading method that works best for your database. For example, a MySQL database can load data from an SQL dump file stored in Amazon S3.

The official MySQL image published on Docker Hub includes facilities for populating the database at startup. These containers will automatically execute *.sql, *sql.gz, and *.sh files stored in the /docker-entrypoint-initdb.d directory. Here is an example of a shell script to download a SQL dump file from your S3 bucket and load it into the database.


    #!/bin/bash

    # Set up the database connection
    DB_USER='your_db_user'
    DB_PASSWORD='your_db_password'
    DB_HOST='your_db_host'
    DB_NAME='your_db_name'
    
    # Download the SQL dump file from S3
    aws s3 cp s3://your_bucket_name/path/to/dumpfile.sql dumpfile.sql
    
    # Load the SQL dump file into the database
    mysql -u $DB_USER -p $DB_PASSWORD -h $DB_HOST $DB_NAME < dumpfile.sql
    
    # Clean up the downloaded file
    rm dumpfile.sql
    
    
Figure 6:Bash script to download an SQL dump file from S3 bucket and load it into a database

Different EaaS providers support different seeding methods; learn more about the seeding methods supported by Uffizzi.

Mock third-party services

Mocking refers to using simulation services that mimic the behavior of real services. This allows developers to test their code without actually calling the service. You can mock third-party services and external API adapters in your code to avoid maintaining multiple test accounts of these services for use in your preview environments.

Here is a sample implementation in which Stripe-based payment functionality is mocked in a preview environment.


    from flask import Flask, jsonify
    from unittest.mock import patch
    
    
    app = Flask(__name__)
    
    
    @app.route('/payment', methods=['POST'])
    def process_payment():
        if app.config['ENV'] == 'production':
            # Call Stripe API
            # ...
            return jsonify({'message': 'Payment processed successfully'})
        else:
            # Mock Stripe API call
            with patch('stripe.Charge.create') as stripe_mock:
                stripe_mock.return_value = {
                    'id': 'ch_1234567890',
                    'amount': 100,
                    'currency': 'usd',
                    'paid': True
                }
                # Process payment
                # ...
            return jsonify({'message': 'Payment processed successfully in mock mode'})
    
    
    if __name__ == '__main__':
        app.run()
    
    
Figure 7: Example server application that mocks a call to the Stripe API

Additional tips for successfully adopting EaaS

Here are some more ideas to keep in mind that may help ensure a good outcome when adopting EaaS:

  • Select an environment-as-a-service provider that supports multiple version control and CI/CD platforms.
  • Be sure the provider offers an ungated demo and free trial so that you can fully assess the service and ensure that it meets your needs.
  • Make sure that the vendor supports your application architecture before adopting its services.
  • Fully sanitize data before seeding databases.

Conclusion

Environment-as-a-service platforms set up and tear down a complete ephemeral application stack for every feature branch allowing each developer or test engineer to run tests in isolation before merging their code with the main branch.

EaaS platforms should integrate with CI/CD platforms like GitHub Actions, container provisioning technologies like Docker compose, and provide their own secret manager and functionality to seed a database.

Be sure to assess any potential EaaS provider before making a commitment to ensure that it meets your needs. Quality providers should offer a live, interactive demo and a free trial.

Uffizzi logo
Environments as a Service
Learn More
preview icon
Empower your devs with an environment for every pull request
time icon
Avoid release delays that cost millions in missed revenue
Velocity icon
Improve development velocity at scale by up to 50%
Lifecycle icon
Plan capacity in real time with lifecycle management built in
Learn More