Mutable vs Immutable Infrastructure

Photo by Joan Gamell on Unsplash

Mutable vs Immutable Infrastructure

ยท

5 min read

Mutable Infrastructure

  1. Definition: In mutable infrastructure, servers and other elements are continuously updated and modified in place. This means that when changes are needed, the existing infrastructure is tweaked or altered without replacing it entirely.

  2. Pros:

    • Flexibility: Easy to make small changes and updates.

    • Familiarity: Traditional approach, well-understood by many IT professionals.

    • Gradual Updates: Allows for incremental changes without overhauling the entire system.

  3. Cons:

    • Configuration Drift: Over time, each server can become unique, leading to inconsistencies.

    • Maintenance Complexity: More difficult to maintain and manage due to variations.

    • Scaling Challenges: Scaling up or down can be complex due to the intertwined components.

Immutable Infrastructure

  1. Definition: Immutable infrastructure treats servers and components as replaceable units. When a change is needed, a new, updated instance is created and replaced wholesale, rather than modifying the existing one.

  2. Pros:

    • Consistency and Reliability: Each deployment is predictable, reducing the risk of "it works on my machine" issues.

    • Scalability: Easier to scale, as new instances are simply replicas of a standard image.

    • Security: Reduces risk of long-term vulnerabilities, as old instances are replaced entirely.

  3. Cons:

    • Resource Intensive: Requires more resources for deploying new instances.

    • Complexity in Management: Managing multiple versions of instances can be complex.

    • Initial Learning Curve: Can be challenging to adopt for teams used to mutable infrastructure.

Tradeoffs

  • Update Frequency vs. Stability: Mutable allows frequent tweaks but can lead to instability, while immutable offers stability but requires larger, less frequent updates.

  • Resource Usage: Immutable infrastructure may demand more resources for deployment but reduces long-term maintenance.

  • Adaptability: Mutable infrastructure is better for environments requiring continuous, small changes. Immutable is suited for environments where consistency and reliability are prioritized.

Externalization of Data in Immutable Infrastructure

  • Importance: In immutable infrastructure, externalizing data is crucial as the servers themselves are frequently replaced. This ensures data persistence across server replacements.

  • Implementation: Data is stored in external databases, storage systems, or services, separated from the main compute instances.

DevOps Tools

  • For Mutable Infrastructure:

    • Configuration Management Tools: Puppet, Chef, Ansible. These tools help in managing and automating the configuration of servers.

    • Monitoring Tools: Nagios, Zabbix. Used for monitoring the state of servers and applications.

  • For Immutable Infrastructure:

    • Containerization Tools: Docker, Kubernetes. These are essential for creating, deploying, and managing containers.

    • Infrastructure as Code (IaC) Tools: Terraform, AWS CloudFormation. These tools are used for scripting and automating the setup of infrastructure.

    • Continuous Integration/Continuous Deployment (CI/CD) Tools: Jenkins, GitLab CI. Facilitates the automated testing and deployment of new immutable instances.

The choice between mutable and immutable infrastructure depends on the specific needs, scale, and existing practices of an organization. Each approach has its strengths and challenges, and often a hybrid approach is adopted to leverage the benefits of both.

Example deploy of web application with mutable and immutable approach

Let's consider a simple web application for this example. We'll use a basic Python Flask application for both the mutable and immutable infrastructure scenarios. This application will display a simple webpage with a message.

๐Ÿ’ก
As a server you can use AWS EC2 instance. To launch an EC2 instance follow this guide: How to launch a single EC2 instance via AWS CLI

Part 1: Mutable Infrastructure with Ansible

App Setup:

  1. The Flask app (app.py) might look like this:

     from flask import Flask
     app = Flask(__name__)
    
     @app.route('/')
     def hello_world():
         return 'Hello, World! Version 1'
    
     if __name__ == '__main__':
         app.run(host='0.0.0.0')
    
  2. Ansible Playbook (app_update.yml): This playbook updates the application to a new version. The new version of the app (app_v2.py) might have a different message:

     ---
     - hosts: ec2_instances
       tasks:
         - name: Install Python and Flask
           apt:
             name: "{{ packages }}"
           vars:
             packages:
               - python3
               - python3-pip
           become: yes
    
         - name: Copy new version of the app
           copy:
             src: /path/to/app_v2.py
             dest: /home/ubuntu/app.py
    
         - name: Install Flask
           pip:
             name: flask
    
         - name: Restart application
           command: python3 /home/ubuntu/app.py
    
  3. Update Process: Run the playbook to update the application on your EC2 instance.

Part 2: Immutable Infrastructure with Terraform

App Setup:

  1. The initial version of the Flask app (app.py) is the same as in the mutable example.

  2. Terraform Configuration (main.tf): Define an EC2 instance that runs the Flask application. Include user data to install Python, Flask, and run the app:

     resource "aws_instance" "app_server" {
       ami = "ami-123456" # Use a suitable AMI
       instance_type = "t2.micro"
       key_name = "your_key_pair"
    
       user_data = <<-EOF
                   #!/bin/bash
                   apt-get update
                   apt-get install -y python3 python3-pip
                   pip3 install flask
                   echo 'from flask import Flask\napp = Flask(__name__)\n@app.route("/")\ndef hello_world():\n    return "Hello, World! Version 1"\nif __name__ == "__main__":\n    app.run(host="0.0.0.0")' > /home/ubuntu/app.py
                   python3 /home/ubuntu/app.py &
                   EOF
    
       tags = {
         Name = "Immutable Flask App Server"
       }
     }
    
  3. Deployment Process: Initialize Terraform and apply the configuration to create a new EC2 instance with the Flask app running.

  4. Application Update: To update the application, modify the user_data in the Terraform configuration with the new version of the Flask app and apply the changes.

This example showcases how to handle a basic Flask application with mutable and immutable infrastructure. The mutable approach updates the application in-place, while the immutable approach replaces the entire EC2 instance with a new one containing the updated application.

References:

  1. What is Mutable vs. Immutable Infrastructure?

  2. A Tale of Two Terraforms โ€” A Model for Managing Immutable and Mutable Infrastructure

  3. Why we use Terraform and not Chef, Puppet, Ansible, Pulumi, or CloudFormation

ย